From c0dbf903fe0ce41f26464de7075dc85f9f464b26 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Mon, 27 Mar 2023 12:00:59 -0300 Subject: [PATCH 01/39] refactor: transfer auction winner from riskfund --- contracts/RiskFund/IRiskFund.sol | 6 ++- contracts/RiskFund/RiskFund.sol | 17 ++++--- contracts/Shortfall/IShortfall.sol | 11 ----- contracts/Shortfall/Shortfall.sol | 18 +++----- deploy/014-riskfund-protocolshare.ts | 2 +- tests/hardhat/Fork/RiskFund.ts | 23 ++++------ tests/hardhat/Fork/RiskFundSwap.ts | 1 - tests/hardhat/Shortfall.ts | 69 ++++++++++++++++------------ 8 files changed, 70 insertions(+), 77 deletions(-) delete mode 100644 contracts/Shortfall/IShortfall.sol diff --git a/contracts/RiskFund/IRiskFund.sol b/contracts/RiskFund/IRiskFund.sol index 3c5bc980f..56e0eab31 100644 --- a/contracts/RiskFund/IRiskFund.sol +++ b/contracts/RiskFund/IRiskFund.sol @@ -13,7 +13,11 @@ interface IRiskFund { address[][] calldata paths ) external returns (uint256); - function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256); + function transferReserveForAuction( + address comptroller, + address highestBidder, + uint256 amount + ) external returns (uint256); function updateAssetsState(address comptroller, address asset) external; diff --git a/contracts/RiskFund/RiskFund.sol b/contracts/RiskFund/RiskFund.sol index 43febf108..2c9ea8e6f 100644 --- a/contracts/RiskFund/RiskFund.sol +++ b/contracts/RiskFund/RiskFund.sol @@ -14,7 +14,6 @@ import { ComptrollerViewInterface } from "../ComptrollerInterface.sol"; import { Comptroller } from "../Comptroller.sol"; import { PoolRegistry } from "../Pool/PoolRegistry.sol"; import { IPancakeswapV2Router } from "../IPancakeswapV2Router.sol"; -import { IShortfall } from "../Shortfall/IShortfall.sol"; import { MaxLoopsLimitHelper } from "../MaxLoopsLimitHelper.sol"; import { ensureNonzeroAddress } from "../lib/validators.sol"; @@ -118,10 +117,6 @@ contract RiskFund is */ function setShortfallContractAddress(address shortfallContractAddress_) external onlyOwner { ensureNonzeroAddress(shortfallContractAddress_); - require( - IShortfall(shortfallContractAddress_).convertibleBaseAsset() == convertibleBaseAsset, - "Risk Fund: Base asset doesn't match" - ); address oldShortfallContractAddress = shortfall; shortfall = shortfallContractAddress_; @@ -200,14 +195,18 @@ contract RiskFund is * @param amount Amount to be transferred to auction contract. * @return Number reserved tokens. */ - function transferReserveForAuction(address comptroller, uint256 amount) external override returns (uint256) { - address shortfall_ = shortfall; - require(msg.sender == shortfall_, "Risk fund: Only callable by Shortfall contract"); + function transferReserveForAuction( + address comptroller, + address highestBidder, + uint256 amount + ) external override returns (uint256) { + require(msg.sender == shortfall, "Risk fund: Only callable by Shortfall contract"); require(amount <= poolReserves[comptroller], "Risk Fund: Insufficient pool reserve."); unchecked { poolReserves[comptroller] = poolReserves[comptroller] - amount; } - IERC20Upgradeable(convertibleBaseAsset).safeTransfer(shortfall_, amount); + + IERC20Upgradeable(convertibleBaseAsset).transfer(highestBidder, amount); emit TransferredReserveForAuction(comptroller, amount); diff --git a/contracts/Shortfall/IShortfall.sol b/contracts/Shortfall/IShortfall.sol deleted file mode 100644 index 48eedbd55..000000000 --- a/contracts/Shortfall/IShortfall.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity 0.8.13; - -/** - * @title IShortfall - * @author Venus - * @notice Interface implemented by `Shortfall`. - */ -interface IShortfall { - function convertibleBaseAsset() external returns (address); -} diff --git a/contracts/Shortfall/Shortfall.sol b/contracts/Shortfall/Shortfall.sol index 64717d070..a839b2445 100644 --- a/contracts/Shortfall/Shortfall.sol +++ b/contracts/Shortfall/Shortfall.sol @@ -7,11 +7,9 @@ import { SafeERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; import { AccessControlledV8 } from "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol"; - import { VToken } from "../VToken.sol"; import { ComptrollerInterface, ComptrollerViewInterface } from "../ComptrollerInterface.sol"; import { IRiskFund } from "../RiskFund/IRiskFund.sol"; -import { IShortfall } from "./IShortfall.sol"; import { PoolRegistry } from "../Pool/PoolRegistry.sol"; import { PoolRegistryInterface } from "../Pool/PoolRegistryInterface.sol"; import { ensureNonzeroAddress } from "../lib/validators.sol"; @@ -27,7 +25,7 @@ import { EXP_SCALE } from "../lib/constants.sol"; * if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the * risk fund in exchange for paying off all the pool's bad debt. */ -contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGuardUpgradeable, IShortfall { +contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGuardUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; /// @notice Type of auction @@ -88,9 +86,6 @@ contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGua /// @notice Time to wait for first bidder. initially waits for 100 blocks uint256 public waitForFirstBidder; - /// @notice base asset contract address - address public convertibleBaseAsset; - /// @notice Auctions for each pool mapping(address => Auction) public auctions; @@ -152,7 +147,6 @@ contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGua /** * @notice Initialize the shortfall contract - * @param convertibleBaseAsset_ Asset to swap the funds to * @param riskFund_ RiskFund contract address * @param minimumPoolBadDebt_ Minimum bad debt in base asset for a pool to start auction * @param accessControlManager_ AccessControlManager contract address @@ -160,12 +154,10 @@ contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGua * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero */ function initialize( - address convertibleBaseAsset_, IRiskFund riskFund_, uint256 minimumPoolBadDebt_, address accessControlManager_ ) external initializer { - ensureNonzeroAddress(convertibleBaseAsset_); ensureNonzeroAddress(address(riskFund_)); require(minimumPoolBadDebt_ != 0, "invalid minimum pool bad debt"); @@ -173,7 +165,6 @@ contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGua __AccessControlled_init_unchained(accessControlManager_); __ReentrancyGuard_init(); minimumPoolBadDebt = minimumPoolBadDebt_; - convertibleBaseAsset = convertibleBaseAsset_; riskFund = riskFund_; waitForFirstBidder = DEFAULT_WAIT_FOR_FIRST_BIDDER; nextBidderBlockLimit = DEFAULT_NEXT_BIDDER_BLOCK_LIMIT; @@ -277,8 +268,11 @@ contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGua riskFundBidAmount = (auction.seizedRiskFund * auction.highestBidBps) / MAX_BPS; } - uint256 transferredAmount = riskFund.transferReserveForAuction(comptroller, riskFundBidAmount); - IERC20Upgradeable(convertibleBaseAsset).safeTransfer(auction.highestBidder, riskFundBidAmount); + uint256 transferredAmount = riskFund.transferReserveForAuction( + comptroller, + auction.highestBidder, + riskFundBidAmount + ); emit AuctionClosed( comptroller, diff --git a/deploy/014-riskfund-protocolshare.ts b/deploy/014-riskfund-protocolshare.ts index da6fe7118..8fa61ec2e 100644 --- a/deploy/014-riskfund-protocolshare.ts +++ b/deploy/014-riskfund-protocolshare.ts @@ -99,7 +99,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { proxyContract: "OpenZeppelinTransparentProxy", execute: { methodName: "initialize", - args: [BUSD.address, riskFund.address, MIN_POOL_BAD_DEBT, accessControl.address], + args: [riskFund.address, MIN_POOL_BAD_DEBT, accessControl.address], }, upgradeIndex: 0, }, diff --git a/tests/hardhat/Fork/RiskFund.ts b/tests/hardhat/Fork/RiskFund.ts index 4dc92cf97..bc0dcdc25 100644 --- a/tests/hardhat/Fork/RiskFund.ts +++ b/tests/hardhat/Fork/RiskFund.ts @@ -127,7 +127,6 @@ const riskFundFixture = async (): Promise => { to: shortfall.address, value: ethers.utils.parseEther("1"), // 1 ether }); - shortfall.convertibleBaseAsset.returns(BUSD.address); const RiskFund = await ethers.getContractFactory("RiskFund"); riskFund = (await upgrades.deployProxy(RiskFund, [ @@ -436,7 +435,6 @@ describe("Risk Fund: Tests", function () { it("emits ShortfallContractUpdated event", async function () { const newShortfall = await smock.fake("Shortfall"); - await newShortfall.convertibleBaseAsset.returns(BUSD.address); const tx = riskFund.setShortfallContractAddress(newShortfall.address); await expect(tx) .to.emit(riskFund, "ShortfallContractUpdated") @@ -723,18 +721,22 @@ describe("Risk Fund: Tests", function () { expect(pool2Reserve).equal(0); }); }); - // myContract.connect(myFake.wallet).doSomething(); + describe("Transfer to Auction contract", async function () { it("Revert while transfering funds to Auction contract", async function () { await expect( - riskFund.connect(busdUser).transferReserveForAuction(comptroller1Proxy.address, convertToUnit(30, 18)), + riskFund + .connect(busdUser) + .transferReserveForAuction(comptroller1Proxy.address, busdUser.address, convertToUnit(30, 18)), ).to.be.revertedWith("Risk fund: Only callable by Shortfall contract"); const auctionContract = shortfall.address; await riskFund.setShortfallContractAddress(auctionContract); await expect( - riskFund.connect(shortfall.wallet).transferReserveForAuction(comptroller1Proxy.address, convertToUnit(100, 18)), + riskFund + .connect(shortfall.wallet) + .transferReserveForAuction(comptroller1Proxy.address, busdUser.address, convertToUnit(100, 18)), ).to.be.revertedWith("Risk Fund: Insufficient pool reserve."); }); @@ -777,23 +779,19 @@ describe("Risk Fund: Tests", function () { ], ); - const beforeTransfer = await BUSD.balanceOf(shortfall.address); await riskFund .connect(shortfall.wallet) - .transferReserveForAuction(comptroller1Proxy.address, convertToUnit(20, 18)); - const afterTransfer = await BUSD.balanceOf(shortfall.address); + .transferReserveForAuction(comptroller1Proxy.address, busdUser.address, convertToUnit(20, 18)); const remainingBalance = await BUSD.balanceOf(riskFund.address); const poolReserve = await riskFund.poolReserves(comptroller1Proxy.address); - const amount = Number(afterTransfer) - Number(beforeTransfer); - expect(amount).to.be.closeTo(Number(convertToUnit(20, 18)), Number(convertToUnit(3, 17))); expect(remainingBalance).equal(poolReserve); }); it("Should revert the transfer to auction transaction", async function () { const [admin] = await ethers.getSigners(); const auctionContract = await smock.fake("Shortfall"); - await auctionContract.convertibleBaseAsset.returns(BUSD.address); + await riskFund.setShortfallContractAddress(auctionContract.address); await USDC.connect(usdcUser).approve(vUSDC.address, convertToUnit(1000, 18)); @@ -834,7 +832,7 @@ describe("Risk Fund: Tests", function () { ); await expect( - riskFund.transferReserveForAuction(comptroller1Proxy.address, convertToUnit(20, 18)), + riskFund.transferReserveForAuction(comptroller1Proxy.address, busdUser.address, convertToUnit(20, 18)), ).to.be.revertedWith("Risk fund: Only callable by Shortfall contract"); // reset @@ -847,7 +845,6 @@ describe("Risk Fund: Tests", function () { it("Transfer single asset from multiple pools to riskFund", async function () { const auctionContract = await smock.fake("Shortfall"); - await auctionContract.convertibleBaseAsset.returns(BUSD.address); await riskFund.setShortfallContractAddress(auctionContract.address); diff --git a/tests/hardhat/Fork/RiskFundSwap.ts b/tests/hardhat/Fork/RiskFundSwap.ts index 529a43d92..dddc0cc98 100644 --- a/tests/hardhat/Fork/RiskFundSwap.ts +++ b/tests/hardhat/Fork/RiskFundSwap.ts @@ -106,7 +106,6 @@ const riskFundFixture = async (): Promise => { const Shortfall = await ethers.getContractFactory("Shortfall"); const shortfall = await upgrades.deployProxy(Shortfall, [ - BUSD.address, AddressOne, parseUnits("10000", 18), fakeAccessControlManager.address, diff --git a/tests/hardhat/Shortfall.ts b/tests/hardhat/Shortfall.ts index 94aa6dbde..4410eb591 100644 --- a/tests/hardhat/Shortfall.ts +++ b/tests/hardhat/Shortfall.ts @@ -12,11 +12,12 @@ import { AccessControlManager, Comptroller, Comptroller__factory, - IRiskFund, MockDeflatingToken, MockToken, PoolRegistry, ResilientOracleInterface, + RiskFund, + RiskFund__factory, Shortfall, Shortfall__factory, VToken, @@ -33,7 +34,7 @@ let bidder1: SignerWithAddress; let bidder2: SignerWithAddress; let shortfall: MockContract; let accessControlManager: AccessControlManager; -let fakeRiskFund: FakeContract; +let mockRiskFund: MockContract; let mockBUSD: MockToken; let mockDAI: MockToken; let mockWBTC: MockToken; @@ -58,16 +59,19 @@ async function shortfallFixture() { const AccessControlManagerFactor = await ethers.getContractFactory("AccessControlManager"); accessControlManager = await AccessControlManagerFactor.deploy(); - fakeRiskFund = await smock.fake("IRiskFund"); + + const RiskFund = await smock.mock("RiskFund"); + mockRiskFund = await RiskFund.deploy(); const Shortfall = await smock.mock("Shortfall"); shortfall = await upgrades.deployProxy(Shortfall, [ - mockBUSD.address, - fakeRiskFund.address, + mockRiskFund.address, parseUnits(minimumPoolBadDebt, "18"), accessControlManager.address, ]); + await mockRiskFund.setVariable("shortfall", shortfall.address); + [owner, someone, bidder1, bidder2] = await ethers.getSigners(); poolRegistry = await smock.fake("PoolRegistry"); @@ -90,6 +94,12 @@ async function shortfallFixture() { comptroller = await Comptroller.deploy(poolRegistry.address); poolAddress = comptroller.address; + await mockRiskFund.setVariable("poolReserves", { + [comptroller.address]: parseUnits(riskFundBalance, 18), + }); + + await mockRiskFund.setVariable("convertibleBaseAsset", mockBUSD.address); + poolRegistry.getPoolByComptroller.returns({ name: "test", creator: AddressOne, @@ -139,8 +149,7 @@ async function shortfallFixture() { comptroller.oracle.returns(fakePriceOracle.address); - fakeRiskFund.poolReserves.returns(parseUnits(riskFundBalance, 18)); - fakeRiskFund.transferReserveForAuction.returns(0); + mockRiskFund.transferReserveForAuction.returns(0); // Access Control await accessControlManager.giveCallPermission(shortfall.address, "updateIncentiveBps(uint256)", owner.address); @@ -331,8 +340,6 @@ describe("Shortfall: Tests", async function () { vDAI.badDebt.returns(parseUnits("1000", 18)); vWBTC.badDebt.returns(parseUnits("1", 8)); - expect(await fakeRiskFund.poolReserves(comptroller.address)).equal(parseUnits(riskFundBalance, 18).toString()); - expect(await vDAI.badDebt()).equal(parseUnits("1000", 18)); expect(await vWBTC.badDebt()).equal(parseUnits("1", 8)); }); @@ -466,9 +473,8 @@ describe("Shortfall: Tests", async function () { const originalBalance = await mockBUSD.balanceOf(bidder2.address); await mine((await shortfall.nextBidderBlockLimit()).toNumber() + 2); - // simulate transferReserveForAuction - await mockBUSD.transfer(shortfall.address, parseUnits(riskFundBalance, 18)); - fakeRiskFund.transferReserveForAuction.returns(parseUnits("10000", 18)); + // transfer "reserves" to risk fund + await mockBUSD.transfer(mockRiskFund.address, parseUnits(riskFundBalance, 18)); await expect(shortfall.closeAuction(poolAddress)) .to.emit(shortfall, "AuctionClosed") @@ -495,7 +501,12 @@ describe("Shortfall: Tests", async function () { }); describe("LARGE_RISK_FUND Scenario", async function () { - before(setup); + before(async () => { + await setup(); + await mockRiskFund.setVariable("poolReserves", { + [comptroller.address]: parseUnits("10000000", 18), + }); + }); let startBlockNumber; it("Start auction", async function () { vDAI.badDebt.returns(parseUnits("10000", 18)); @@ -504,7 +515,6 @@ describe("Shortfall: Tests", async function () { await vWBTC.setVariable("badDebt", parseUnits("1", 8)); riskFundBalance = "50000"; - fakeRiskFund.poolReserves.returns(parseUnits(riskFundBalance, 18)); const receipt = await shortfall.startAuction(poolAddress); startBlockNumber = receipt.blockNumber; @@ -584,9 +594,8 @@ describe("Shortfall: Tests", async function () { await mine((await shortfall.nextBidderBlockLimit()).toNumber() + 2); - // simulate transferReserveForAuction - await mockBUSD.transfer(shortfall.address, auction.seizedRiskFund); - fakeRiskFund.transferReserveForAuction.returns("6138067320000000000000"); + // transfer "reserves" to risk fund + await mockBUSD.transfer(mockRiskFund.address, auction.seizedRiskFund); await expect(shortfall.closeAuction(poolAddress)) .to.emit(shortfall, "AuctionClosed") @@ -655,8 +664,8 @@ describe("Shortfall: Tests", async function () { await mockDAI.approve(shortfall.address, parseUnits("50000", 18)); await mockWBTC.approve(shortfall.address, parseUnits("50000", 8)); - // simulate transferReserveForAuction - await mockBUSD.transfer(shortfall.address, auction.seizedRiskFund); + // transfer "reserves" to risk fund + await mockBUSD.transfer(mockRiskFund.address, auction.seizedRiskFund); await shortfall.placeBid(poolAddress, auction.startBidBps, auction.startBlock); @@ -679,6 +688,9 @@ describe("Shortfall: Tests", async function () { await shortfall.startAuction(poolAddress); const auction = await shortfall.auctions(poolAddress); + // transfer "reserves" to risk fund + await mockBUSD.connect(owner).transfer(mockRiskFund.address, auction.seizedRiskFund); + await mockDAI.approve(shortfall.address, parseUnits("50000", 18)); await mockWBTC.approve(shortfall.address, parseUnits("50000", 8)); @@ -703,10 +715,10 @@ describe("Shortfall: Tests", async function () { }); it("can close current auction but not start new one when they are paused", async function () { - vDAI.badDebt.returns(parseUnits("10000", 18)); - await vDAI.setVariable("badDebt", parseUnits("10000", 18)); - vWBTC.badDebt.returns(parseUnits("2", 8)); - await vWBTC.setVariable("badDebt", parseUnits("2", 8)); + vDAI.badDebt.returns(parseUnits("1000", 18)); + await vDAI.setVariable("badDebt", parseUnits("1000", 18)); + vWBTC.badDebt.returns(parseUnits("1", 8)); + await vWBTC.setVariable("badDebt", parseUnits("1", 8)); await shortfall.startAuction(poolAddress); const auction = await shortfall.auctions(poolAddress); @@ -715,7 +727,7 @@ describe("Shortfall: Tests", async function () { .to.emit(shortfall, "AuctionsPaused") .withArgs(owner.address); - await shortfall.placeBid(poolAddress, auction.startBidBps, auction.startBlock); + await shortfall.placeBid(poolAddress, auction.startBidBps.add(1), auction.startBlock); // Close out auction created for this test case await mine(10); await expect(shortfall.closeAuction(poolAddress)); @@ -737,7 +749,7 @@ describe("Shortfall: Deflationary token Scenario", async function () { await vFloki.setVariable("badDebt", parseUnits("100", 18)); riskFundBalance = "500"; - fakeRiskFund.poolReserves.returns(parseUnits(riskFundBalance, 18)); + mockRiskFund.poolReserves.returns(parseUnits(riskFundBalance, 18)); await shortfall.connect(owner).updateMinimumPoolBadDebt(convertToUnit(10, 18)); @@ -774,9 +786,8 @@ describe("Shortfall: Deflationary token Scenario", async function () { await mine((await shortfall.nextBidderBlockLimit()).toNumber() + 2); - // simulate transferReserveForAuction - await mockBUSD.transfer(shortfall.address, auction.seizedRiskFund); - fakeRiskFund.transferReserveForAuction.returns(convertToUnit("100", 18)); + // transfer "reserves" to risk fund + await mockBUSD.transfer(mockRiskFund.address, auction.seizedRiskFund); const tx = await shortfall.closeAuction(poolAddress); await expect(tx) @@ -786,7 +797,7 @@ describe("Shortfall: Deflationary token Scenario", async function () { startBlockNumber, bidder2.address, 120, - convertToUnit("100", 18), + convertToUnit("1.32", 18), [vDAI.address, vWBTC.address, vFloki.address], ["0", "0", "98010000000000000000"], ); From d8d49de42c718fdeceb6bf31da5dc9265ccaf191 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 28 Mar 2023 11:21:47 -0300 Subject: [PATCH 02/39] feat: make convertibleBaseAsset configurable --- contracts/RiskFund/RiskFund.sol | 17 +++++++++++++++++ tests/hardhat/Fork/RiskFund.ts | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/contracts/RiskFund/RiskFund.sol b/contracts/RiskFund/RiskFund.sol index 2c9ea8e6f..5831e0dd0 100644 --- a/contracts/RiskFund/RiskFund.sol +++ b/contracts/RiskFund/RiskFund.sol @@ -47,6 +47,9 @@ contract RiskFund is /// @notice Emitted when shortfall contract address is updated event ShortfallContractUpdated(address indexed oldShortfallContract, address indexed newShortfallContract); + /// @notice Emitted when convertible base asset is updated + event ConvertibleBaseAssetUpdated(address indexed oldConvertibleBaseAsset, address indexed newConvertibleBaseAsset); + /// @notice Emitted when PancakeSwap router contract address is updated event PancakeSwapRouterUpdated(address indexed oldPancakeSwapRouter, address indexed newPancakeSwapRouter); @@ -147,6 +150,20 @@ contract RiskFund is emit MinAmountToConvertUpdated(oldMinAmountToConvert, minAmountToConvert_); } + /** + * @notice Sets a new convertible base asset + * @param _convertibleBaseAsset Address for new convertible base asset. + */ + function setConvertibleBaseAsset(address _convertibleBaseAsset) external { + _checkAccessAllowed("setConvertibleBaseAsset(address)"); + require(_convertibleBaseAsset != address(0), "Risk Fund: new convertible base asset address invalid"); + + address oldConvertibleBaseAsset = convertibleBaseAsset; + convertibleBaseAsset = _convertibleBaseAsset; + + emit ConvertibleBaseAssetUpdated(oldConvertibleBaseAsset, _convertibleBaseAsset); + } + /** * @notice Swap array of pool assets into base asset's tokens of at least a minimum amount * @param markets Array of vTokens whose assets to swap for base asset diff --git a/tests/hardhat/Fork/RiskFund.ts b/tests/hardhat/Fork/RiskFund.ts index bc0dcdc25..d7d39a902 100644 --- a/tests/hardhat/Fork/RiskFund.ts +++ b/tests/hardhat/Fork/RiskFund.ts @@ -208,6 +208,8 @@ const riskFundFixture = async (): Promise => { admin.address, ); + await accessControlManager.giveCallPermission(riskFund.address, "setConvertibleBaseAsset(address)", admin.address); + await shortfall.connect(shortfall.wallet).updatePoolRegistry(poolRegistry.address); const _closeFactor = convertToUnit(0.05, 18); @@ -548,6 +550,28 @@ describe("Risk Fund: Tests", function () { await expect(tx).to.emit(riskFund, "MinAmountToConvertUpdated").withArgs(convertToUnit(10, 18), 1); }); }); + + describe("setConvertibleBaseAsset", async function () { + it("only callable by allowed accounts", async function () { + await expect(riskFund.connect(busdUser).setConvertibleBaseAsset(USDT.address)).to.be.revertedWithCustomError( + riskFund, + "Unauthorized", + ); + }); + + it("reverts on invalid convertible base asset", async function () { + const [admin] = await ethers.getSigners(); + await expect( + riskFund.connect(admin).setConvertibleBaseAsset("0x0000000000000000000000000000000000000000"), + ).to.be.revertedWith("Risk Fund: new convertible base asset address invalid"); + }); + + it("should emit events on success", async function () { + const [admin] = await ethers.getSigners(); + const tx = riskFund.connect(admin).setConvertibleBaseAsset(USDT.address); + await expect(tx).to.emit(riskFund, "ConvertibleBaseAssetUpdated").withArgs(BUSD.address, USDT.address); + }); + }); }); describe("Risk fund transfers", async function () { From cd8168c22a41d23c978a0522c52dd4f481a312d4 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Wed, 5 Apr 2023 11:54:17 -0500 Subject: [PATCH 03/39] refactor: add USDT to deployment script --- helpers/deploymentConfig.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index 769ca2982..d892e4be0 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -192,6 +192,13 @@ export const globalConfig: NetworkConfig = { decimals: 18, tokenAddress: ethers.constants.AddressZero, }, + { + isMock: true, + name: "Tether", + symbol: "USDT", + decimals: 18, + tokenAddress: ethers.constants.AddressZero, + }, { isMock: true, name: "Bitcoin BEP2", @@ -512,7 +519,7 @@ export const globalConfig: NetworkConfig = { }, { isMock: false, - name: "USDT", + name: "Tether", symbol: "USDT", decimals: 6, tokenAddress: "0xA11c8D9DC9b66E209Ef60F0C8D969D3CD988782c", @@ -622,7 +629,7 @@ export const globalConfig: NetworkConfig = { { isMock: false, name: "Binance-Peg BSC-USD", - symbol: "USDT", + symbol: "BUSD", decimals: 18, tokenAddress: "0x55d398326f99059fF775485246999027B3197955", }, From 6f19a78eb4704c8b66967e01abd71a8f43144e57 Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Thu, 20 Jul 2023 10:49:47 +0000 Subject: [PATCH 04/39] chore(release): 1.3.0 [skip ci] ## [1.3.0](https://github.com/VenusProtocol/isolated-pools/compare/v1.2.0...v1.3.0) (2023-07-20) ### Features * make convertibleBaseAsset configurable ([d8d49de](https://github.com/VenusProtocol/isolated-pools/commit/d8d49de42c718fdeceb6bf31da5dc9265ccaf191)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f07e3fc64..309a34354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [1.3.0](https://github.com/VenusProtocol/isolated-pools/compare/v1.2.0...v1.3.0) (2023-07-20) + + +### Features + +* make convertibleBaseAsset configurable ([d8d49de](https://github.com/VenusProtocol/isolated-pools/commit/d8d49de42c718fdeceb6bf31da5dc9265ccaf191)) + ## [1.2.0](https://github.com/VenusProtocol/isolated-pools/compare/v1.1.0...v1.2.0) (2023-07-12) diff --git a/package.json b/package.json index 3f1f88b80..410575e9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "1.2.0", + "version": "1.3.0", "description": "", "files": [ "artifacts", From 2ec639a9280ce507ccfe29e03f8ccc08fe7ef45b Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 10 Aug 2023 12:05:52 +0300 Subject: [PATCH 05/39] chore: use incremental indexes for rewards distributors Problem: We're going to have several rewards distributors with the same reward token in the same pool. This would lead to collisions in deployment names. Solution: Change deployment postfix to "_{poolId}_{index}", so that when a new rewards distributor is appended to the rewards array, it gets deployed regardless of whether reward token collides. --- deploy/010-deploy-reward-distributors.ts | 6 +- deploy/012-transfer-pools-ownership.ts | 2 +- deploy/013-vip-based-config.ts | 4 +- deployments/bscmainnet.json | 88 +++++++-------- ...Fi.json => RewardsDistributor_DeFi_0.json} | 0 ...n => RewardsDistributor_DeFi_0_Proxy.json} | 0 ...Fi.json => RewardsDistributor_DeFi_1.json} | 0 ...n => RewardsDistributor_DeFi_1_Proxy.json} | 0 ....json => RewardsDistributor_GameFi_0.json} | 0 ...=> RewardsDistributor_GameFi_0_Proxy.json} | 0 ....json => RewardsDistributor_GameFi_1.json} | 0 ...=> RewardsDistributor_GameFi_1_Proxy.json} | 0 ...RewardsDistributor_LiquidStakedBNB_0.json} | 0 ...sDistributor_LiquidStakedBNB_0_Proxy.json} | 0 ...RewardsDistributor_LiquidStakedBNB_1.json} | 0 ...sDistributor_LiquidStakedBNB_1_Proxy.json} | 0 ...RewardsDistributor_LiquidStakedBNB_2.json} | 0 ...sDistributor_LiquidStakedBNB_2_Proxy.json} | 0 ... => RewardsDistributor_Stablecoins_0.json} | 0 ...wardsDistributor_Stablecoins_0_Proxy.json} | 0 ...on.json => RewardsDistributor_Tron_0.json} | 0 ...n => RewardsDistributor_Tron_0_Proxy.json} | 0 ...on.json => RewardsDistributor_Tron_1.json} | 0 ...n => RewardsDistributor_Tron_1_Proxy.json} | 0 ...on.json => RewardsDistributor_Tron_2.json} | 0 ...n => RewardsDistributor_Tron_2_Proxy.json} | 0 ...on.json => RewardsDistributor_Tron_3.json} | 0 ...n => RewardsDistributor_Tron_3_Proxy.json} | 0 deployments/bsctestnet.json | 100 +++++++++--------- ...Fi.json => RewardsDistributor_DeFi_0.json} | 0 ...n => RewardsDistributor_DeFi_0_Proxy.json} | 0 ...Fi.json => RewardsDistributor_DeFi_1.json} | 0 ...n => RewardsDistributor_DeFi_1_Proxy.json} | 0 ....json => RewardsDistributor_GameFi_0.json} | 0 ...=> RewardsDistributor_GameFi_0_Proxy.json} | 0 ....json => RewardsDistributor_GameFi_1.json} | 0 ...=> RewardsDistributor_GameFi_1_Proxy.json} | 0 ...RewardsDistributor_LiquidStakedBNB_0.json} | 0 ...sDistributor_LiquidStakedBNB_0_Proxy.json} | 0 ...RewardsDistributor_LiquidStakedBNB_1.json} | 0 ...sDistributor_LiquidStakedBNB_1_Proxy.json} | 0 ...RewardsDistributor_LiquidStakedBNB_2.json} | 0 ...sDistributor_LiquidStakedBNB_2_Proxy.json} | 0 ... => RewardsDistributor_StableCoins_0.json} | 0 ...wardsDistributor_StableCoins_0_Proxy.json} | 0 ...on.json => RewardsDistributor_Tron_0.json} | 0 ...n => RewardsDistributor_Tron_0_Proxy.json} | 0 ...on.json => RewardsDistributor_Tron_1.json} | 0 ...n => RewardsDistributor_Tron_1_Proxy.json} | 0 ...on.json => RewardsDistributor_Tron_2.json} | 0 ...n => RewardsDistributor_Tron_2_Proxy.json} | 0 ...on.json => RewardsDistributor_Tron_3.json} | 0 ...n => RewardsDistributor_Tron_3_Proxy.json} | 0 53 files changed, 101 insertions(+), 99 deletions(-) rename deployments/bscmainnet/{RewardsDistributor_BSW_DeFi.json => RewardsDistributor_DeFi_0.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_BSW_DeFi_Proxy.json => RewardsDistributor_DeFi_0_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_ANKR_DeFi.json => RewardsDistributor_DeFi_1.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_ANKR_DeFi_Proxy.json => RewardsDistributor_DeFi_1_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_FLOKI_GameFi.json => RewardsDistributor_GameFi_0.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_FLOKI_GameFi_Proxy.json => RewardsDistributor_GameFi_0_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_RACA_GameFi.json => RewardsDistributor_GameFi_1.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_RACA_GameFi_Proxy.json => RewardsDistributor_GameFi_1_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_ankrBNB_LiquidStakedBNB.json => RewardsDistributor_LiquidStakedBNB_0.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_ankrBNB_LiquidStakedBNB_Proxy.json => RewardsDistributor_LiquidStakedBNB_0_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_stkBNB_LiquidStakedBNB.json => RewardsDistributor_LiquidStakedBNB_1.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_stkBNB_LiquidStakedBNB_Proxy.json => RewardsDistributor_LiquidStakedBNB_1_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_SD_LiquidStakedBNB.json => RewardsDistributor_LiquidStakedBNB_2.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_SD_LiquidStakedBNB_Proxy.json => RewardsDistributor_LiquidStakedBNB_2_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_HAY_Stablecoins.json => RewardsDistributor_Stablecoins_0.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_HAY_Stablecoins_Proxy.json => RewardsDistributor_Stablecoins_0_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_BTT_Tron.json => RewardsDistributor_Tron_0.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_BTT_Tron_Proxy.json => RewardsDistributor_Tron_0_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_WIN_Tron.json => RewardsDistributor_Tron_1.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_WIN_Tron_Proxy.json => RewardsDistributor_Tron_1_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_TRX_Tron.json => RewardsDistributor_Tron_2.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_TRX_Tron_Proxy.json => RewardsDistributor_Tron_2_Proxy.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_USDD_Tron.json => RewardsDistributor_Tron_3.json} (100%) rename deployments/bscmainnet/{RewardsDistributor_USDD_Tron_Proxy.json => RewardsDistributor_Tron_3_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_BSW_DeFi.json => RewardsDistributor_DeFi_0.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_BSW_DeFi_Proxy.json => RewardsDistributor_DeFi_0_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_ANKR_DeFi.json => RewardsDistributor_DeFi_1.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_ANKR_DeFi_Proxy.json => RewardsDistributor_DeFi_1_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_FLOKI_GameFi.json => RewardsDistributor_GameFi_0.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_FLOKI_GameFi_Proxy.json => RewardsDistributor_GameFi_0_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_RACA_GameFi.json => RewardsDistributor_GameFi_1.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_RACA_GameFi_Proxy.json => RewardsDistributor_GameFi_1_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_ankrBNB_LiquidStakedBNB.json => RewardsDistributor_LiquidStakedBNB_0.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_ankrBNB_LiquidStakedBNB_Proxy.json => RewardsDistributor_LiquidStakedBNB_0_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_stkBNB_LiquidStakedBNB.json => RewardsDistributor_LiquidStakedBNB_1.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_stkBNB_LiquidStakedBNB_Proxy.json => RewardsDistributor_LiquidStakedBNB_1_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_SD_LiquidStakedBNB.json => RewardsDistributor_LiquidStakedBNB_2.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_SD_LiquidStakedBNB_Proxy.json => RewardsDistributor_LiquidStakedBNB_2_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_HAY_StableCoins.json => RewardsDistributor_StableCoins_0.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_HAY_StableCoins_Proxy.json => RewardsDistributor_StableCoins_0_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_BTT_Tron.json => RewardsDistributor_Tron_0.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_BTT_Tron_Proxy.json => RewardsDistributor_Tron_0_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_WIN_Tron.json => RewardsDistributor_Tron_1.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_WIN_Tron_Proxy.json => RewardsDistributor_Tron_1_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_TRX_Tron.json => RewardsDistributor_Tron_2.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_TRX_Tron_Proxy.json => RewardsDistributor_Tron_2_Proxy.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_USDD_Tron.json => RewardsDistributor_Tron_3.json} (100%) rename deployments/bsctestnet/{RewardsDistributor_USDD_Tron_Proxy.json => RewardsDistributor_Tron_3_Proxy.json} (100%) diff --git a/deploy/010-deploy-reward-distributors.ts b/deploy/010-deploy-reward-distributors.ts index 2cb5fcbdb..059c64467 100644 --- a/deploy/010-deploy-reward-distributors.ts +++ b/deploy/010-deploy-reward-distributors.ts @@ -26,18 +26,19 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { from: deployer, autoMine: true, log: true, + skipIfAlreadyDeployed: true, }); for (const pool of pools) { const rewards = pool.rewards; if (!rewards) continue; const comptrollerProxy = await ethers.getContract(`Comptroller_${pool.id}`); - for (const reward of rewards) { + for (const [idx, reward] of rewards.entries()) { // Get reward token address const tokenConfig = getTokenConfig(reward.asset, tokensConfig); const rewardTokenAddress = await getTokenAddress(tokenConfig, deployments); // Custom contract name so we can obtain the proxy after that easily - const contractName = `RewardsDistributor_${reward.asset}_${pool.id}`; + const contractName = `RewardsDistributor_${pool.id}_${idx}`; await deploy(contractName, { from: deployer, contract: "RewardsDistributor", @@ -53,6 +54,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { }, autoMine: true, log: true, + skipIfAlreadyDeployed: true, }); } } diff --git a/deploy/012-transfer-pools-ownership.ts b/deploy/012-transfer-pools-ownership.ts index b8fada716..c37ffa125 100644 --- a/deploy/012-transfer-pools-ownership.ts +++ b/deploy/012-transfer-pools-ownership.ts @@ -12,7 +12,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const rewardsDistributors = poolConfig .map((pool: PoolConfig) => { const rewards = pool.rewards || []; - return rewards.map((reward: RewardConfig) => `RewardsDistributor_${reward.asset}_${pool.id}`); + return rewards.map((_, idx: number) => `RewardsDistributor_${pool.id}_${idx}`); }) .flat(); diff --git a/deploy/013-vip-based-config.ts b/deploy/013-vip-based-config.ts index 1be61cbdc..6d0d61c04 100644 --- a/deploy/013-vip-based-config.ts +++ b/deploy/013-vip-based-config.ts @@ -82,8 +82,8 @@ const configureRewards = async ( unregisteredRewardDistributors.map(async (pool: PoolConfig) => { const rewards = pool.rewards || []; const poolCommands = await Promise.all( - rewards.map(async (rewardConfig: RewardConfig) => { - const contractName = `RewardsDistributor_${rewardConfig.asset}_${pool.id}`; + rewards.map(async (rewardConfig: RewardConfig, idx: number) => { + const contractName = `RewardsDistributor_${pool.id}_${idx}`; const rewardsDistributor = await ethers.getContract(contractName); return [ ...(await acceptOwnership(contractName, owner, hre)), diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index c036485bf..26c7c873c 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -7538,8 +7538,8 @@ } ] }, - "RewardsDistributor_ANKR_DeFi": { - "address": "0x14d9A428D0f35f81A30ca8D8b2F3974D3CccB98B", + "RewardsDistributor_DeFi_0": { + "address": "0x7524116CEC937ef17B5998436F16d1306c4F7EF8", "abi": [ { "anonymous": false, @@ -8670,8 +8670,8 @@ } ] }, - "RewardsDistributor_ANKR_DeFi_Proxy": { - "address": "0x14d9A428D0f35f81A30ca8D8b2F3974D3CccB98B", + "RewardsDistributor_DeFi_0_Proxy": { + "address": "0x7524116CEC937ef17B5998436F16d1306c4F7EF8", "abi": [ { "inputs": [ @@ -8819,8 +8819,8 @@ } ] }, - "RewardsDistributor_BSW_DeFi": { - "address": "0x7524116CEC937ef17B5998436F16d1306c4F7EF8", + "RewardsDistributor_DeFi_1": { + "address": "0x14d9A428D0f35f81A30ca8D8b2F3974D3CccB98B", "abi": [ { "anonymous": false, @@ -9951,8 +9951,8 @@ } ] }, - "RewardsDistributor_BSW_DeFi_Proxy": { - "address": "0x7524116CEC937ef17B5998436F16d1306c4F7EF8", + "RewardsDistributor_DeFi_1_Proxy": { + "address": "0x14d9A428D0f35f81A30ca8D8b2F3974D3CccB98B", "abi": [ { "inputs": [ @@ -10100,8 +10100,8 @@ } ] }, - "RewardsDistributor_BTT_Tron": { - "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", + "RewardsDistributor_GameFi_0": { + "address": "0x501a91b995Bd41177503A1A4144F3D25BFF869e1", "abi": [ { "anonymous": false, @@ -11232,8 +11232,8 @@ } ] }, - "RewardsDistributor_BTT_Tron_Proxy": { - "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", + "RewardsDistributor_GameFi_0_Proxy": { + "address": "0x501a91b995Bd41177503A1A4144F3D25BFF869e1", "abi": [ { "inputs": [ @@ -11381,8 +11381,8 @@ } ] }, - "RewardsDistributor_FLOKI_GameFi": { - "address": "0x501a91b995Bd41177503A1A4144F3D25BFF869e1", + "RewardsDistributor_GameFi_1": { + "address": "0x2517A3bEe42EA8f628926849B04870260164b555", "abi": [ { "anonymous": false, @@ -12513,8 +12513,8 @@ } ] }, - "RewardsDistributor_FLOKI_GameFi_Proxy": { - "address": "0x501a91b995Bd41177503A1A4144F3D25BFF869e1", + "RewardsDistributor_GameFi_1_Proxy": { + "address": "0x2517A3bEe42EA8f628926849B04870260164b555", "abi": [ { "inputs": [ @@ -12662,8 +12662,8 @@ } ] }, - "RewardsDistributor_HAY_Stablecoins": { - "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", + "RewardsDistributor_LiquidStakedBNB_0": { + "address": "0x63aFCe42086c8302659CA0E21F4Eade27Ad85ded", "abi": [ { "anonymous": false, @@ -13794,8 +13794,8 @@ } ] }, - "RewardsDistributor_HAY_Stablecoins_Proxy": { - "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", + "RewardsDistributor_LiquidStakedBNB_0_Proxy": { + "address": "0x63aFCe42086c8302659CA0E21F4Eade27Ad85ded", "abi": [ { "inputs": [ @@ -13943,8 +13943,8 @@ } ] }, - "RewardsDistributor_RACA_GameFi": { - "address": "0x2517A3bEe42EA8f628926849B04870260164b555", + "RewardsDistributor_LiquidStakedBNB_1": { + "address": "0x79397BAc982718347406Ebb7A6a8845896fdD8dE", "abi": [ { "anonymous": false, @@ -15075,8 +15075,8 @@ } ] }, - "RewardsDistributor_RACA_GameFi_Proxy": { - "address": "0x2517A3bEe42EA8f628926849B04870260164b555", + "RewardsDistributor_LiquidStakedBNB_1_Proxy": { + "address": "0x79397BAc982718347406Ebb7A6a8845896fdD8dE", "abi": [ { "inputs": [ @@ -15224,7 +15224,7 @@ } ] }, - "RewardsDistributor_SD_LiquidStakedBNB": { + "RewardsDistributor_LiquidStakedBNB_2": { "address": "0x6a7b50EccC721f0Fa9FD7879A7dF082cdA60Db78", "abi": [ { @@ -16356,7 +16356,7 @@ } ] }, - "RewardsDistributor_SD_LiquidStakedBNB_Proxy": { + "RewardsDistributor_LiquidStakedBNB_2_Proxy": { "address": "0x6a7b50EccC721f0Fa9FD7879A7dF082cdA60Db78", "abi": [ { @@ -16505,8 +16505,8 @@ } ] }, - "RewardsDistributor_TRX_Tron": { - "address": "0x22af8a65639a351a9D5d77d5a25ea5e1Cf5e9E6b", + "RewardsDistributor_Stablecoins_0": { + "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", "abi": [ { "anonymous": false, @@ -17637,8 +17637,8 @@ } ] }, - "RewardsDistributor_TRX_Tron_Proxy": { - "address": "0x22af8a65639a351a9D5d77d5a25ea5e1Cf5e9E6b", + "RewardsDistributor_Stablecoins_0_Proxy": { + "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", "abi": [ { "inputs": [ @@ -17786,8 +17786,8 @@ } ] }, - "RewardsDistributor_USDD_Tron": { - "address": "0x08e4AFd80A5849FDBa4bBeea86ed470D697e4C54", + "RewardsDistributor_Tron_0": { + "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", "abi": [ { "anonymous": false, @@ -18918,8 +18918,8 @@ } ] }, - "RewardsDistributor_USDD_Tron_Proxy": { - "address": "0x08e4AFd80A5849FDBa4bBeea86ed470D697e4C54", + "RewardsDistributor_Tron_0_Proxy": { + "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", "abi": [ { "inputs": [ @@ -19067,7 +19067,7 @@ } ] }, - "RewardsDistributor_WIN_Tron": { + "RewardsDistributor_Tron_1": { "address": "0x6536123503DF76BDfF8207e4Fb0C594Bc5eFD00A", "abi": [ { @@ -20199,7 +20199,7 @@ } ] }, - "RewardsDistributor_WIN_Tron_Proxy": { + "RewardsDistributor_Tron_1_Proxy": { "address": "0x6536123503DF76BDfF8207e4Fb0C594Bc5eFD00A", "abi": [ { @@ -20348,8 +20348,8 @@ } ] }, - "RewardsDistributor_ankrBNB_LiquidStakedBNB": { - "address": "0x63aFCe42086c8302659CA0E21F4Eade27Ad85ded", + "RewardsDistributor_Tron_2": { + "address": "0x22af8a65639a351a9D5d77d5a25ea5e1Cf5e9E6b", "abi": [ { "anonymous": false, @@ -21480,8 +21480,8 @@ } ] }, - "RewardsDistributor_ankrBNB_LiquidStakedBNB_Proxy": { - "address": "0x63aFCe42086c8302659CA0E21F4Eade27Ad85ded", + "RewardsDistributor_Tron_2_Proxy": { + "address": "0x22af8a65639a351a9D5d77d5a25ea5e1Cf5e9E6b", "abi": [ { "inputs": [ @@ -21629,8 +21629,8 @@ } ] }, - "RewardsDistributor_stkBNB_LiquidStakedBNB": { - "address": "0x79397BAc982718347406Ebb7A6a8845896fdD8dE", + "RewardsDistributor_Tron_3": { + "address": "0x08e4AFd80A5849FDBa4bBeea86ed470D697e4C54", "abi": [ { "anonymous": false, @@ -22761,8 +22761,8 @@ } ] }, - "RewardsDistributor_stkBNB_LiquidStakedBNB_Proxy": { - "address": "0x79397BAc982718347406Ebb7A6a8845896fdD8dE", + "RewardsDistributor_Tron_3_Proxy": { + "address": "0x08e4AFd80A5849FDBa4bBeea86ed470D697e4C54", "abi": [ { "inputs": [ diff --git a/deployments/bscmainnet/RewardsDistributor_BSW_DeFi.json b/deployments/bscmainnet/RewardsDistributor_DeFi_0.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_BSW_DeFi.json rename to deployments/bscmainnet/RewardsDistributor_DeFi_0.json diff --git a/deployments/bscmainnet/RewardsDistributor_BSW_DeFi_Proxy.json b/deployments/bscmainnet/RewardsDistributor_DeFi_0_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_BSW_DeFi_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_DeFi_0_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_ANKR_DeFi.json b/deployments/bscmainnet/RewardsDistributor_DeFi_1.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_ANKR_DeFi.json rename to deployments/bscmainnet/RewardsDistributor_DeFi_1.json diff --git a/deployments/bscmainnet/RewardsDistributor_ANKR_DeFi_Proxy.json b/deployments/bscmainnet/RewardsDistributor_DeFi_1_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_ANKR_DeFi_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_DeFi_1_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_FLOKI_GameFi.json b/deployments/bscmainnet/RewardsDistributor_GameFi_0.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_FLOKI_GameFi.json rename to deployments/bscmainnet/RewardsDistributor_GameFi_0.json diff --git a/deployments/bscmainnet/RewardsDistributor_FLOKI_GameFi_Proxy.json b/deployments/bscmainnet/RewardsDistributor_GameFi_0_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_FLOKI_GameFi_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_GameFi_0_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_RACA_GameFi.json b/deployments/bscmainnet/RewardsDistributor_GameFi_1.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_RACA_GameFi.json rename to deployments/bscmainnet/RewardsDistributor_GameFi_1.json diff --git a/deployments/bscmainnet/RewardsDistributor_RACA_GameFi_Proxy.json b/deployments/bscmainnet/RewardsDistributor_GameFi_1_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_RACA_GameFi_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_GameFi_1_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_ankrBNB_LiquidStakedBNB.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_0.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_ankrBNB_LiquidStakedBNB.json rename to deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_0.json diff --git a/deployments/bscmainnet/RewardsDistributor_ankrBNB_LiquidStakedBNB_Proxy.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_0_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_ankrBNB_LiquidStakedBNB_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_0_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_stkBNB_LiquidStakedBNB.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_1.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_stkBNB_LiquidStakedBNB.json rename to deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_1.json diff --git a/deployments/bscmainnet/RewardsDistributor_stkBNB_LiquidStakedBNB_Proxy.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_1_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_stkBNB_LiquidStakedBNB_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_1_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_SD_LiquidStakedBNB.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_2.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_SD_LiquidStakedBNB.json rename to deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_2.json diff --git a/deployments/bscmainnet/RewardsDistributor_SD_LiquidStakedBNB_Proxy.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_2_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_SD_LiquidStakedBNB_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_2_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_HAY_Stablecoins.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_0.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_HAY_Stablecoins.json rename to deployments/bscmainnet/RewardsDistributor_Stablecoins_0.json diff --git a/deployments/bscmainnet/RewardsDistributor_HAY_Stablecoins_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_0_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_HAY_Stablecoins_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_Stablecoins_0_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_BTT_Tron.json b/deployments/bscmainnet/RewardsDistributor_Tron_0.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_BTT_Tron.json rename to deployments/bscmainnet/RewardsDistributor_Tron_0.json diff --git a/deployments/bscmainnet/RewardsDistributor_BTT_Tron_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Tron_0_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_BTT_Tron_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_Tron_0_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_WIN_Tron.json b/deployments/bscmainnet/RewardsDistributor_Tron_1.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_WIN_Tron.json rename to deployments/bscmainnet/RewardsDistributor_Tron_1.json diff --git a/deployments/bscmainnet/RewardsDistributor_WIN_Tron_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Tron_1_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_WIN_Tron_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_Tron_1_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_TRX_Tron.json b/deployments/bscmainnet/RewardsDistributor_Tron_2.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_TRX_Tron.json rename to deployments/bscmainnet/RewardsDistributor_Tron_2.json diff --git a/deployments/bscmainnet/RewardsDistributor_TRX_Tron_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Tron_2_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_TRX_Tron_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_Tron_2_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_USDD_Tron.json b/deployments/bscmainnet/RewardsDistributor_Tron_3.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_USDD_Tron.json rename to deployments/bscmainnet/RewardsDistributor_Tron_3.json diff --git a/deployments/bscmainnet/RewardsDistributor_USDD_Tron_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Tron_3_Proxy.json similarity index 100% rename from deployments/bscmainnet/RewardsDistributor_USDD_Tron_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_Tron_3_Proxy.json diff --git a/deployments/bsctestnet.json b/deployments/bsctestnet.json index 956ae14f7..60bf9428d 100644 --- a/deployments/bsctestnet.json +++ b/deployments/bsctestnet.json @@ -12626,8 +12626,8 @@ } ] }, - "RewardsDistributor_ANKR_DeFi": { - "address": "0x4be90041D1e082EfE3613099aA3b987D9045d718", + "RewardsDistributor_DeFi_0": { + "address": "0x2b67Cfaf28a1aBbBf71fb814Ad384d0C5a98e0F9", "abi": [ { "anonymous": false, @@ -13758,8 +13758,8 @@ } ] }, - "RewardsDistributor_ANKR_DeFi_Proxy": { - "address": "0x4be90041D1e082EfE3613099aA3b987D9045d718", + "RewardsDistributor_DeFi_0_Proxy": { + "address": "0x2b67Cfaf28a1aBbBf71fb814Ad384d0C5a98e0F9", "abi": [ { "inputs": [ @@ -13907,8 +13907,8 @@ } ] }, - "RewardsDistributor_BSW_DeFi": { - "address": "0x2b67Cfaf28a1aBbBf71fb814Ad384d0C5a98e0F9", + "RewardsDistributor_DeFi_1": { + "address": "0x4be90041D1e082EfE3613099aA3b987D9045d718", "abi": [ { "anonymous": false, @@ -15039,8 +15039,8 @@ } ] }, - "RewardsDistributor_BSW_DeFi_Proxy": { - "address": "0x2b67Cfaf28a1aBbBf71fb814Ad384d0C5a98e0F9", + "RewardsDistributor_DeFi_1_Proxy": { + "address": "0x4be90041D1e082EfE3613099aA3b987D9045d718", "abi": [ { "inputs": [ @@ -15188,8 +15188,8 @@ } ] }, - "RewardsDistributor_BTT_Tron": { - "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", + "RewardsDistributor_GameFi_0": { + "address": "0x5651866bcC4650d6fe5178E5ED7a8Be2cf3F70D0", "abi": [ { "anonymous": false, @@ -16320,8 +16320,8 @@ } ] }, - "RewardsDistributor_BTT_Tron_Proxy": { - "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", + "RewardsDistributor_GameFi_0_Proxy": { + "address": "0x5651866bcC4650d6fe5178E5ED7a8Be2cf3F70D0", "abi": [ { "inputs": [ @@ -16469,8 +16469,8 @@ } ] }, - "RewardsDistributor_FLOKI_GameFi": { - "address": "0x5651866bcC4650d6fe5178E5ED7a8Be2cf3F70D0", + "RewardsDistributor_GameFi_1": { + "address": "0x66E213a4b8ba1c8D62cAa4649C7177E29321E262", "abi": [ { "anonymous": false, @@ -17601,8 +17601,8 @@ } ] }, - "RewardsDistributor_FLOKI_GameFi_Proxy": { - "address": "0x5651866bcC4650d6fe5178E5ED7a8Be2cf3F70D0", + "RewardsDistributor_GameFi_1_Proxy": { + "address": "0x66E213a4b8ba1c8D62cAa4649C7177E29321E262", "abi": [ { "inputs": [ @@ -17750,8 +17750,8 @@ } ] }, - "RewardsDistributor_HAY_StableCoins": { - "address": "0xb0269d68CfdCc30Cb7Cd2E0b52b08Fa7Ffd3079b", + "RewardsDistributor_LiquidStakedBNB_0": { + "address": "0x7df11563c6b6b8027aE619FD9644A647dED5893B", "abi": [ { "anonymous": false, @@ -18882,8 +18882,8 @@ } ] }, - "RewardsDistributor_HAY_StableCoins_Proxy": { - "address": "0xb0269d68CfdCc30Cb7Cd2E0b52b08Fa7Ffd3079b", + "RewardsDistributor_LiquidStakedBNB_0_Proxy": { + "address": "0x7df11563c6b6b8027aE619FD9644A647dED5893B", "abi": [ { "inputs": [ @@ -19031,8 +19031,8 @@ } ] }, - "RewardsDistributor_RACA_GameFi": { - "address": "0x66E213a4b8ba1c8D62cAa4649C7177E29321E262", + "RewardsDistributor_LiquidStakedBNB_1": { + "address": "0x72c770A1E73Ad9ccD5249fC5536346f95345Fe2c", "abi": [ { "anonymous": false, @@ -20163,8 +20163,8 @@ } ] }, - "RewardsDistributor_RACA_GameFi_Proxy": { - "address": "0x66E213a4b8ba1c8D62cAa4649C7177E29321E262", + "RewardsDistributor_LiquidStakedBNB_1_Proxy": { + "address": "0x72c770A1E73Ad9ccD5249fC5536346f95345Fe2c", "abi": [ { "inputs": [ @@ -20312,7 +20312,7 @@ } ] }, - "RewardsDistributor_SD_LiquidStakedBNB": { + "RewardsDistributor_LiquidStakedBNB_2": { "address": "0x8Ad2Ad29e4e2C0606644Be51c853A7A4a3078F85", "abi": [ { @@ -21444,7 +21444,7 @@ } ] }, - "RewardsDistributor_SD_LiquidStakedBNB_Proxy": { + "RewardsDistributor_LiquidStakedBNB_2_Proxy": { "address": "0x8Ad2Ad29e4e2C0606644Be51c853A7A4a3078F85", "abi": [ { @@ -21593,8 +21593,8 @@ } ] }, - "RewardsDistributor_TRX_Tron": { - "address": "0x507401883C2a874D919e78a73dD0cB56f2e7eaD7", + "RewardsDistributor_StableCoins_0": { + "address": "0xb0269d68CfdCc30Cb7Cd2E0b52b08Fa7Ffd3079b", "abi": [ { "anonymous": false, @@ -22725,8 +22725,8 @@ } ] }, - "RewardsDistributor_TRX_Tron_Proxy": { - "address": "0x507401883C2a874D919e78a73dD0cB56f2e7eaD7", + "RewardsDistributor_StableCoins_0_Proxy": { + "address": "0xb0269d68CfdCc30Cb7Cd2E0b52b08Fa7Ffd3079b", "abi": [ { "inputs": [ @@ -22874,8 +22874,8 @@ } ] }, - "RewardsDistributor_USDD_Tron": { - "address": "0x1c50672f4752cc0Ae532D9b93b936C21121Ff08b", + "RewardsDistributor_Tron_0": { + "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", "abi": [ { "anonymous": false, @@ -24006,8 +24006,8 @@ } ] }, - "RewardsDistributor_USDD_Tron_Proxy": { - "address": "0x1c50672f4752cc0Ae532D9b93b936C21121Ff08b", + "RewardsDistributor_Tron_0_Proxy": { + "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", "abi": [ { "inputs": [ @@ -24155,7 +24155,7 @@ } ] }, - "RewardsDistributor_WIN_Tron": { + "RewardsDistributor_Tron_1": { "address": "0x9A73Ba89f6a95611B46b68241aBEcAF2cD0bd78A", "abi": [ { @@ -25287,7 +25287,7 @@ } ] }, - "RewardsDistributor_WIN_Tron_Proxy": { + "RewardsDistributor_Tron_1_Proxy": { "address": "0x9A73Ba89f6a95611B46b68241aBEcAF2cD0bd78A", "abi": [ { @@ -25436,8 +25436,8 @@ } ] }, - "RewardsDistributor_ankrBNB_LiquidStakedBNB": { - "address": "0x7df11563c6b6b8027aE619FD9644A647dED5893B", + "RewardsDistributor_Tron_2": { + "address": "0x507401883C2a874D919e78a73dD0cB56f2e7eaD7", "abi": [ { "anonymous": false, @@ -26568,8 +26568,8 @@ } ] }, - "RewardsDistributor_ankrBNB_LiquidStakedBNB_Proxy": { - "address": "0x7df11563c6b6b8027aE619FD9644A647dED5893B", + "RewardsDistributor_Tron_2_Proxy": { + "address": "0x507401883C2a874D919e78a73dD0cB56f2e7eaD7", "abi": [ { "inputs": [ @@ -26717,8 +26717,8 @@ } ] }, - "RewardsDistributor_stkBNB_LiquidStakedBNB": { - "address": "0x72c770A1E73Ad9ccD5249fC5536346f95345Fe2c", + "RewardsDistributor_Tron_3": { + "address": "0x1c50672f4752cc0Ae532D9b93b936C21121Ff08b", "abi": [ { "anonymous": false, @@ -27849,8 +27849,8 @@ } ] }, - "RewardsDistributor_stkBNB_LiquidStakedBNB_Proxy": { - "address": "0x72c770A1E73Ad9ccD5249fC5536346f95345Fe2c", + "RewardsDistributor_Tron_3_Proxy": { + "address": "0x1c50672f4752cc0Ae532D9b93b936C21121Ff08b", "abi": [ { "inputs": [ @@ -40751,7 +40751,7 @@ ] }, "BinanceOracle_Implementation": { - "address": "0x693A5ae5F9b8da5b8125f9BC0d8f04C7c63d2384", + "address": "0xCd64844CD0E8E34782cd0d1bF3E537bf7b474FAe", "abi": [ { "inputs": [ @@ -41724,7 +41724,7 @@ ] }, "BoundValidator_Implementation": { - "address": "0x0EbBBc805Ed9b6F4FAe2cd3103a3653547018dba", + "address": "0x4915F67a57FDcbA22535F0F021D64b66b095d026", "abi": [ { "inputs": [ @@ -42817,7 +42817,7 @@ ] }, "ChainlinkOracle_Implementation": { - "address": "0xb6D0D2a0B8Eb799Fc1Bcf63D31011878F576EeC3", + "address": "0xa074529FD3d0E7261A730d0f867107BA0C20d74A", "abi": [ { "inputs": [ @@ -44128,7 +44128,7 @@ ] }, "PythOracle_Implementation": { - "address": "0xb830C5F05334a364a80957dDACF5A336dc55Bab2", + "address": "0xb8a450101DF8ab770c8F8521E189a4B39e7Cf5f5", "abi": [ { "inputs": [ @@ -45424,7 +45424,7 @@ ] }, "ResilientOracle_Implementation": { - "address": "0x360506E086d6E4788b0970CD576307CCEccECbe6", + "address": "0xF53cFE89b4c3eFCbdd9aF712e94017454d43c181", "abi": [ { "inputs": [ @@ -46938,7 +46938,7 @@ ] }, "TwapOracle_Implementation": { - "address": "0xA65d9c3593B8ca0EF4C475E16Eb93f92Ca81F98B", + "address": "0x572ec272B4Ae3a50B99905AFd78671F84474ffd1", "abi": [ { "inputs": [ diff --git a/deployments/bsctestnet/RewardsDistributor_BSW_DeFi.json b/deployments/bsctestnet/RewardsDistributor_DeFi_0.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_BSW_DeFi.json rename to deployments/bsctestnet/RewardsDistributor_DeFi_0.json diff --git a/deployments/bsctestnet/RewardsDistributor_BSW_DeFi_Proxy.json b/deployments/bsctestnet/RewardsDistributor_DeFi_0_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_BSW_DeFi_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_DeFi_0_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_ANKR_DeFi.json b/deployments/bsctestnet/RewardsDistributor_DeFi_1.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_ANKR_DeFi.json rename to deployments/bsctestnet/RewardsDistributor_DeFi_1.json diff --git a/deployments/bsctestnet/RewardsDistributor_ANKR_DeFi_Proxy.json b/deployments/bsctestnet/RewardsDistributor_DeFi_1_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_ANKR_DeFi_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_DeFi_1_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_FLOKI_GameFi.json b/deployments/bsctestnet/RewardsDistributor_GameFi_0.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_FLOKI_GameFi.json rename to deployments/bsctestnet/RewardsDistributor_GameFi_0.json diff --git a/deployments/bsctestnet/RewardsDistributor_FLOKI_GameFi_Proxy.json b/deployments/bsctestnet/RewardsDistributor_GameFi_0_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_FLOKI_GameFi_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_GameFi_0_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_RACA_GameFi.json b/deployments/bsctestnet/RewardsDistributor_GameFi_1.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_RACA_GameFi.json rename to deployments/bsctestnet/RewardsDistributor_GameFi_1.json diff --git a/deployments/bsctestnet/RewardsDistributor_RACA_GameFi_Proxy.json b/deployments/bsctestnet/RewardsDistributor_GameFi_1_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_RACA_GameFi_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_GameFi_1_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_ankrBNB_LiquidStakedBNB.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_0.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_ankrBNB_LiquidStakedBNB.json rename to deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_0.json diff --git a/deployments/bsctestnet/RewardsDistributor_ankrBNB_LiquidStakedBNB_Proxy.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_0_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_ankrBNB_LiquidStakedBNB_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_0_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_stkBNB_LiquidStakedBNB.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_1.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_stkBNB_LiquidStakedBNB.json rename to deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_1.json diff --git a/deployments/bsctestnet/RewardsDistributor_stkBNB_LiquidStakedBNB_Proxy.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_1_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_stkBNB_LiquidStakedBNB_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_1_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_SD_LiquidStakedBNB.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_2.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_SD_LiquidStakedBNB.json rename to deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_2.json diff --git a/deployments/bsctestnet/RewardsDistributor_SD_LiquidStakedBNB_Proxy.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_2_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_SD_LiquidStakedBNB_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_2_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_HAY_StableCoins.json b/deployments/bsctestnet/RewardsDistributor_StableCoins_0.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_HAY_StableCoins.json rename to deployments/bsctestnet/RewardsDistributor_StableCoins_0.json diff --git a/deployments/bsctestnet/RewardsDistributor_HAY_StableCoins_Proxy.json b/deployments/bsctestnet/RewardsDistributor_StableCoins_0_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_HAY_StableCoins_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_StableCoins_0_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_BTT_Tron.json b/deployments/bsctestnet/RewardsDistributor_Tron_0.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_BTT_Tron.json rename to deployments/bsctestnet/RewardsDistributor_Tron_0.json diff --git a/deployments/bsctestnet/RewardsDistributor_BTT_Tron_Proxy.json b/deployments/bsctestnet/RewardsDistributor_Tron_0_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_BTT_Tron_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_Tron_0_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_WIN_Tron.json b/deployments/bsctestnet/RewardsDistributor_Tron_1.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_WIN_Tron.json rename to deployments/bsctestnet/RewardsDistributor_Tron_1.json diff --git a/deployments/bsctestnet/RewardsDistributor_WIN_Tron_Proxy.json b/deployments/bsctestnet/RewardsDistributor_Tron_1_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_WIN_Tron_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_Tron_1_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_TRX_Tron.json b/deployments/bsctestnet/RewardsDistributor_Tron_2.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_TRX_Tron.json rename to deployments/bsctestnet/RewardsDistributor_Tron_2.json diff --git a/deployments/bsctestnet/RewardsDistributor_TRX_Tron_Proxy.json b/deployments/bsctestnet/RewardsDistributor_Tron_2_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_TRX_Tron_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_Tron_2_Proxy.json diff --git a/deployments/bsctestnet/RewardsDistributor_USDD_Tron.json b/deployments/bsctestnet/RewardsDistributor_Tron_3.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_USDD_Tron.json rename to deployments/bsctestnet/RewardsDistributor_Tron_3.json diff --git a/deployments/bsctestnet/RewardsDistributor_USDD_Tron_Proxy.json b/deployments/bsctestnet/RewardsDistributor_Tron_3_Proxy.json similarity index 100% rename from deployments/bsctestnet/RewardsDistributor_USDD_Tron_Proxy.json rename to deployments/bsctestnet/RewardsDistributor_Tron_3_Proxy.json From 30325ea4a680f2b81457ce7f72f857292ccf18bf Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 10 Aug 2023 16:11:27 +0300 Subject: [PATCH 06/39] feat: deploy HAY rewards distributor --- deployments/bscmainnet.json | 1283 ++++++++++++++++- .../RewardsDistributor_Stablecoins_1.json | 1278 ++++++++++++++++ ...ewardsDistributor_Stablecoins_1_Proxy.json | 285 ++++ deployments/bsctestnet.json | 1283 ++++++++++++++++- .../RewardsDistributor_StableCoins_1.json | 1270 ++++++++++++++++ ...ewardsDistributor_StableCoins_1_Proxy.json | 277 ++++ .../eb0bf20bff58bb7e4d4e0c36acf29863.json | 282 ++++ helpers/deploymentConfig.ts | 12 + 8 files changed, 5968 insertions(+), 2 deletions(-) create mode 100644 deployments/bscmainnet/RewardsDistributor_Stablecoins_1.json create mode 100644 deployments/bscmainnet/RewardsDistributor_Stablecoins_1_Proxy.json create mode 100644 deployments/bsctestnet/RewardsDistributor_StableCoins_1.json create mode 100644 deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json create mode 100644 deployments/bsctestnet/solcInputs/eb0bf20bff58bb7e4d4e0c36acf29863.json diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index 26c7c873c..fccb083c8 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -17786,6 +17786,1287 @@ } ] }, + "RewardsDistributor_Stablecoins_1": { + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RewardsDistributor_Stablecoins_1_Proxy": { + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, "RewardsDistributor_Tron_0": { "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", "abi": [ @@ -35212,4 +36493,4 @@ ] } } -} +} \ No newline at end of file diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_1.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_1.json new file mode 100644 index 000000000..f6cf23abb --- /dev/null +++ b/deployments/bscmainnet/RewardsDistributor_Stablecoins_1.json @@ -0,0 +1,1278 @@ +{ + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "transactionIndex": 82, + "gasUsed": "861817", + "logsBloom": "0x00000000010000000000000000000000400000000000000000800000000000000000000000000001000000000000000000200000000000000000000000008000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000010000000000000000000000084000000000000800100000000000000000000002000000400000000000000800000000000000000000000000020000000000000000001040000000200000400000000000000001020000000000200000000000000000000000000000800000000000000000004000000", + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b", + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "logs": [ + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000001251d4ef6bb9f56c8bef7d3a201f00f4c122589" + ], + "data": "0x", + "logIndex": 243, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000055a9f5374af30e3045fb491f1da3c2e8a74d168d" + ], + "data": "0x", + "logIndex": 244, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", + "logIndex": 245, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 246, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 247, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 248, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + } + ], + "blockNumber": 30728477, + "cumulativeGasUsed": "7757159", + "status": 1, + "byzantium": true + }, + "args": [ + "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0xbe20309400000000000000000000000094c1495cd4c557f1560cbd68eab0d197e62915710000000000000000000000000782b6d8c4551b9760e74c0545a9bcd90bdc41e500000000000000000000000000000000000000000000000000000000000000640000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571", + "0x0782b6d8c4551B9760e74c0545a9bCD90bdc41E5", + 100, + "0x4788629ABc6cFCA10F9f969efdEAa1cF70c23555" + ] + }, + "implementation": "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_1_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_1_Proxy.json new file mode 100644 index 000000000..24ecc85bf --- /dev/null +++ b/deployments/bscmainnet/RewardsDistributor_Stablecoins_1_Proxy.json @@ -0,0 +1,285 @@ +{ + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "transactionIndex": 82, + "gasUsed": "861817", + "logsBloom": "0x00000000010000000000000000000000400000000000000000800000000000000000000000000001000000000000000000200000000000000000000000008000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000010000000000000000000000084000000000000800100000000000000000000002000000400000000000000800000000000000000000000000020000000000000000001040000000200000400000000000000001020000000000200000000000000000000000000000800000000000000000004000000", + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b", + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "logs": [ + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000001251d4ef6bb9f56c8bef7d3a201f00f4c122589" + ], + "data": "0x", + "logIndex": 243, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000055a9f5374af30e3045fb491f1da3c2e8a74d168d" + ], + "data": "0x", + "logIndex": 244, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", + "logIndex": 245, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 246, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 247, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + }, + { + "transactionIndex": 82, + "blockNumber": 30728477, + "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 248, + "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" + } + ], + "blockNumber": 30728477, + "cumulativeGasUsed": "7757159", + "status": 1, + "byzantium": true + }, + "args": [ + "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0xbe20309400000000000000000000000094c1495cd4c557f1560cbd68eab0d197e62915710000000000000000000000000782b6d8c4551b9760e74c0545a9bcd90bdc41e500000000000000000000000000000000000000000000000000000000000000640000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsctestnet.json b/deployments/bsctestnet.json index 60bf9428d..e4a8f67ae 100644 --- a/deployments/bsctestnet.json +++ b/deployments/bsctestnet.json @@ -22874,6 +22874,1287 @@ } ] }, + "RewardsDistributor_StableCoins_1": { + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RewardsDistributor_StableCoins_1_Proxy": { + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, "RewardsDistributor_Tron_0": { "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", "abi": [ @@ -47731,4 +49012,4 @@ ] } } -} +} \ No newline at end of file diff --git a/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json b/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json new file mode 100644 index 000000000..b083be577 --- /dev/null +++ b/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json @@ -0,0 +1,1270 @@ +{ + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "transactionIndex": 0, + "gasUsed": "865817", + "logsBloom": "0x1000000000000000000000000000000040000000000000000080000800000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000002000001000000000000000000000000001000000000020000000000000000000800000000800000000000000000000000400000000040000000000000000000000000000000000080000000000000800000010000000000000002002000000400000000000000800000000000000000000000000020000000000000000001040000000000000400000000000000000020000000000200000000000000000000000000000800000000000000000000800001", + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2", + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000fae44cf6309598c2557bb265bf0401d594db97da" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", + "logIndex": 2, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 3, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 4, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", + "logIndex": 5, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + } + ], + "blockNumber": 32321303, + "cumulativeGasUsed": "865817", + "status": 1, + "byzantium": true + }, + "args": [ + "0xfAE44cf6309598c2557Bb265BF0401D594db97DA", + "0xef480a5654b231ff7d80A0681F938f3Db71a6Ca6", + "0xbe20309400000000000000000000000010b57706ad2345e590c2ea4dc02faef0d9f5b08b000000000000000000000000e73774dfcd551bf75650772dc2cc56a2b6323453000000000000000000000000000000000000000000000000000000000000006400000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0x10b57706AD2345e590c2eA4DC02faef0d9f5b08B", + "0xe73774DfCD551BF75650772dC2cC56a2B6323453", + 100, + "0x45f8a08F534f34A97187626E05d4b6648Eeaa9AA" + ] + }, + "implementation": "0xfAE44cf6309598c2557Bb265BF0401D594db97DA", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json b/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json new file mode 100644 index 000000000..ef3c25a64 --- /dev/null +++ b/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json @@ -0,0 +1,277 @@ +{ + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "transactionIndex": 0, + "gasUsed": "865817", + "logsBloom": "0x1000000000000000000000000000000040000000000000000080000800000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000002000001000000000000000000000000001000000000020000000000000000000800000000800000000000000000000000400000000040000000000000000000000000000000000080000000000000800000010000000000000002002000000400000000000000800000000000000000000000000020000000000000000001040000000000000400000000000000000020000000000200000000000000000000000000000800000000000000000000800001", + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2", + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000fae44cf6309598c2557bb265bf0401d594db97da" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", + "logIndex": 2, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 3, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 4, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + }, + { + "transactionIndex": 0, + "blockNumber": 32321303, + "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", + "logIndex": 5, + "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + } + ], + "blockNumber": 32321303, + "cumulativeGasUsed": "865817", + "status": 1, + "byzantium": true + }, + "args": [ + "0xfAE44cf6309598c2557Bb265BF0401D594db97DA", + "0xef480a5654b231ff7d80A0681F938f3Db71a6Ca6", + "0xbe20309400000000000000000000000010b57706ad2345e590c2ea4dc02faef0d9f5b08b000000000000000000000000e73774dfcd551bf75650772dc2cc56a2b6323453000000000000000000000000000000000000000000000000000000000000006400000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsctestnet/solcInputs/eb0bf20bff58bb7e4d4e0c36acf29863.json b/deployments/bsctestnet/solcInputs/eb0bf20bff58bb7e4d4e0c36acf29863.json new file mode 100644 index 000000000..226fe1aad --- /dev/null +++ b/deployments/bsctestnet/solcInputs/eb0bf20bff58bb7e4d4e0c36acf29863.json @@ -0,0 +1,282 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides 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} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\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" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\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" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20Upgradeable 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\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. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\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[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\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 {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\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 * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\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 * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\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 revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\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 * _Available since v3.1._\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" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/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 */\nabstract contract 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() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1967.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967 {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the proxy with `beacon`.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity\n * constructor.\n *\n * Requirements:\n *\n * - `beacon` must be a contract with the interface {IBeacon}.\n */\n constructor(address beacon, bytes memory data) payable {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n\n /**\n * @dev Returns the current beacon address.\n */\n function _beacon() internal view virtual returns (address) {\n return _getBeacon();\n }\n\n /**\n * @dev Returns the current implementation address of the associated beacon.\n */\n function _implementation() internal view virtual override returns (address) {\n return IBeacon(_getBeacon()).implementation();\n }\n\n /**\n * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n *\n * Requirements:\n *\n * - `beacon` must be a contract.\n * - The implementation returned by `beacon` must be a contract.\n */\n function _setBeacon(address beacon, bytes memory data) internal virtual {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n address private _implementation;\n\n /**\n * @dev Emitted when the implementation returned by the beacon is changed.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n * beacon.\n */\n constructor(address implementation_) {\n _setImplementation(implementation_);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function implementation() public view virtual override returns (address) {\n return _implementation;\n }\n\n /**\n * @dev Upgrades the beacon to a new implementation.\n *\n * Emits an {Upgraded} event.\n *\n * Requirements:\n *\n * - msg.sender must be the owner of the contract.\n * - `newImplementation` must be a contract.\n */\n function upgradeTo(address newImplementation) public virtual onlyOwner {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Sets the implementation contract address for this beacon\n *\n * Requirements:\n *\n * - `newImplementation` must be a contract.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n _implementation = newImplementation;\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/IERC1967.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967Upgrade is IERC1967 {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\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 * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\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 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 */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title Venus Access Control Contract.\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\n * The contract allows the owner to set an AccessControlManager contract address.\n * It can restrict method calls based on the sender's role and the method's signature.\n */\n\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\n /// @notice Access control manager contract\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\n error Unauthorized(address sender, address calledContract, string methodSignature);\n\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n }\n\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Sets the address of AccessControlManager\n * @dev Admin function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n * @custom:event Emits NewAccessControlManager event\n * @custom:access Only Governance\n */\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Returns the address of the access control manager contract\n */\n function accessControlManager() external view returns (IAccessControlManagerV8) {\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\n }\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title Venus Access Control Contract\n * @author venus\n * @dev This contract is a wrapper of OpenZeppelin AccessControl\n *\t\textending it in a way to standartize access control\n *\t\twithin Venus Smart Contract Ecosystem\n */\ncontract AccessControlManager is AccessControl, IAccessControlManagerV8 {\n /// @notice Emitted when an account is given a permission to a certain contract function\n /// @dev If contract address is 0x000..0 this means that the account is a default admin of this function and\n /// can call any contract function with this signature\n event PermissionGranted(address account, address contractAddress, string functionSig);\n\n /// @notice Emitted when an account is revoked a permission to a certain contract function\n event PermissionRevoked(address account, address contractAddress, string functionSig);\n\n constructor() {\n // Grant the contract deployer the default admin role: it will be able\n // to grant and revoke any roles\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\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 * @param contractAddress address of contract for which call permissions will be granted\n * @dev if contractAddress is zero address, the account can access the specified function\n * on **any** contract managed by this ACL\n * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n * @param accountToPermit account that will be given access to the contract function\n * @custom:event Emits a {RoleGranted} and {PermissionGranted} events.\n */\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n grantRole(role, accountToPermit);\n emit PermissionGranted(accountToPermit, contractAddress, functionSig);\n }\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(uint256,bool)\"\n * @custom:event Emits {RoleRevoked} and {PermissionRevoked} events.\n */\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n revokeRole(role, accountToRevoke);\n emit PermissionRevoked(accountToRevoke, contractAddress, functionSig);\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev Since restricted contracts using this function as a permission hook, we can get contracts address with msg.sender\n * @param account for which call permissions will be checked\n * @param functionSig restricted function signature e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n *\n */\n function isAllowedToCall(address account, string calldata functionSig) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(msg.sender, functionSig));\n\n if (hasRole(role, account)) {\n return true;\n } else {\n role = keccak256(abi.encodePacked(address(0), functionSig));\n return hasRole(role, account);\n }\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev This function is used as a view function to check permissions rather than contract hook for access restriction check.\n * @param account for which call permissions will be checked against\n * @param contractAddress address of the restricted contract\n * @param functionSig signature of the restricted function e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n */\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n return hasRole(role, account);\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\ninterface IAccessControlManagerV8 is IAccessControl {\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\n\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) external;\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/oracle/contracts/interfaces/FeedRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface FeedRegistryInterface {\n function latestRoundDataByName(\n string memory base,\n string memory quote\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function decimalsByName(string memory base, string memory quote) external view returns (uint8);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface OracleInterface {\n function getPrice(address asset) external view returns (uint256);\n}\n\ninterface ResilientOracleInterface is OracleInterface {\n function updatePrice(address vToken) external;\n\n function updateAssetPrice(address asset) external;\n\n function getUnderlyingPrice(address vToken) external view returns (uint256);\n}\n\ninterface TwapInterface is OracleInterface {\n function updateTwap(address asset) external returns (uint256);\n}\n\ninterface BoundValidatorInterface {\n function validatePriceWithAnchorPrice(\n address asset,\n uint256 reporterPrice,\n uint256 anchorPrice\n ) external view returns (bool);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/PublicResolverInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity 0.8.13;\n\ninterface PublicResolverInterface {\n function addr(bytes32 node) external view returns (address payable);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/SIDRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity 0.8.13;\n\ninterface SIDRegistryInterface {\n function resolver(bytes32 node) external view returns (address);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/VBep20Interface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface VBep20Interface is IERC20Metadata {\n /**\n * @notice Underlying asset for this VToken\n */\n function underlying() external view returns (address);\n}\n" + }, + "@venusprotocol/oracle/contracts/oracles/BinanceOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/SIDRegistryInterface.sol\";\nimport \"../interfaces/FeedRegistryInterface.sol\";\nimport \"../interfaces/PublicResolverInterface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport \"../interfaces/OracleInterface.sol\";\n\n/**\n * @title BinanceOracle\n * @author Venus\n * @notice This oracle fetches price of assets from Binance.\n */\ncontract BinanceOracle is AccessControlledV8, OracleInterface {\n address public sidRegistryAddress;\n\n /// @notice Set this as asset address for BNB. This is the underlying address for vBNB\n address public constant BNB_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n /// @notice Max stale period configuration for assets\n mapping(string => uint256) public maxStalePeriod;\n\n /// @notice Override symbols to be compatible with Binance feed registry\n mapping(string => string) public symbols;\n\n event MaxStalePeriodAdded(string indexed asset, uint256 maxStalePeriod);\n\n event SymbolOverridden(string indexed symbol, string overriddenSymbol);\n\n /**\n * @notice Checks whether an address is null or not\n */\n modifier notNullAddress(address someone) {\n if (someone == address(0)) revert(\"can't be zero address\");\n _;\n }\n\n /// @notice Constructor for the implementation contract.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Used to set the max stale period of an asset\n * @param symbol The symbol of the asset\n * @param _maxStalePeriod The max stake period\n */\n function setMaxStalePeriod(string memory symbol, uint256 _maxStalePeriod) external {\n _checkAccessAllowed(\"setMaxStalePeriod(string,uint256)\");\n if (_maxStalePeriod == 0) revert(\"stale period can't be zero\");\n if (bytes(symbol).length == 0) revert(\"symbol cannot be empty\");\n\n maxStalePeriod[symbol] = _maxStalePeriod;\n emit MaxStalePeriodAdded(symbol, _maxStalePeriod);\n }\n\n /**\n * @notice Used to override a symbol when fetching price\n * @param symbol The symbol to override\n * @param overrideSymbol The symbol after override\n */\n function setSymbolOverride(string calldata symbol, string calldata overrideSymbol) external {\n _checkAccessAllowed(\"setSymbolOverride(string,string)\");\n if (bytes(symbol).length == 0) revert(\"symbol cannot be empty\");\n\n symbols[symbol] = overrideSymbol;\n emit SymbolOverridden(symbol, overrideSymbol);\n }\n\n /**\n * @notice Sets the contracts required to fetch prices\n * @param _sidRegistryAddress Address of SID registry\n * @param _accessControlManager Address of the access control manager contract\n */\n function initialize(\n address _sidRegistryAddress,\n address _accessControlManager\n ) external initializer notNullAddress(_sidRegistryAddress) {\n sidRegistryAddress = _sidRegistryAddress;\n __AccessControlled_init(_accessControlManager);\n }\n\n /**\n * @notice Uses Space ID to fetch the feed registry address\n * @return feedRegistryAddress Address of binance oracle feed registry.\n */\n function getFeedRegistryAddress() public view returns (address) {\n bytes32 nodeHash = 0x94fe3821e0768eb35012484db4df61890f9a6ca5bfa984ef8ff717e73139faff;\n\n SIDRegistryInterface sidRegistry = SIDRegistryInterface(sidRegistryAddress);\n address publicResolverAddress = sidRegistry.resolver(nodeHash);\n PublicResolverInterface publicResolver = PublicResolverInterface(publicResolverAddress);\n\n return publicResolver.addr(nodeHash);\n }\n\n /**\n * @notice Gets the price of a asset from the binance oracle\n * @param asset Address of the asset\n * @return Price in USD\n */\n function getPrice(address asset) public view returns (uint256) {\n string memory symbol;\n uint256 decimals;\n\n if (asset == BNB_ADDR) {\n symbol = \"BNB\";\n decimals = 18;\n } else {\n IERC20Metadata token = IERC20Metadata(asset);\n symbol = token.symbol();\n decimals = token.decimals();\n }\n\n string memory overrideSymbol = symbols[symbol];\n\n if (bytes(overrideSymbol).length != 0) {\n symbol = overrideSymbol;\n }\n\n return _getPrice(symbol, decimals);\n }\n\n function _getPrice(string memory symbol, uint256 decimals) internal view returns (uint256) {\n FeedRegistryInterface feedRegistry = FeedRegistryInterface(getFeedRegistryAddress());\n\n (, int256 answer, , uint256 updatedAt, ) = feedRegistry.latestRoundDataByName(symbol, \"USD\");\n if (answer <= 0) revert(\"invalid binance oracle price\");\n if (block.timestamp < updatedAt) revert(\"updatedAt exceeds block time\");\n\n uint256 deltaTime;\n unchecked {\n deltaTime = block.timestamp - updatedAt;\n }\n if (deltaTime > maxStalePeriod[symbol]) revert(\"binance oracle price expired\");\n\n uint256 decimalDelta = feedRegistry.decimalsByName(symbol, \"USD\");\n return (uint256(answer) * (10 ** (18 - decimalDelta))) * (10 ** (18 - decimals));\n }\n}\n" + }, + "@venusprotocol/oracle/contracts/oracles/ChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\n/**\n * @title ChainlinkOracle\n * @author Venus\n * @notice This oracle fetches prices of assets from the Chainlink oracle.\n */\ncontract ChainlinkOracle is AccessControlledV8, OracleInterface {\n struct TokenConfig {\n /// @notice Underlying token address, which can't be a null address\n /// @notice Used to check if a token is supported\n /// @notice 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB for BNB\n address asset;\n /// @notice Chainlink feed address\n address feed;\n /// @notice Price expiration period of this asset\n uint256 maxStalePeriod;\n }\n\n /// @notice Set this as asset address for BNB. This is the underlying address for vBNB\n address public constant BNB_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n /// @notice Manually set an override price, useful under extenuating conditions such as price feed failure\n mapping(address => uint256) public prices;\n\n /// @notice Token config by assets\n mapping(address => TokenConfig) public tokenConfigs;\n\n /// @notice Emit when a price is manually set\n event PricePosted(address indexed asset, uint256 previousPriceMantissa, uint256 newPriceMantissa);\n\n /// @notice Emit when a token config is added\n event TokenConfigAdded(address indexed asset, address feed, uint256 maxStalePeriod);\n\n modifier notNullAddress(address someone) {\n if (someone == address(0)) revert(\"can't be zero address\");\n _;\n }\n\n /// @notice Constructor for the implementation contract.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Manually set the price of a given asset\n * @param asset Asset address\n * @param price Asset price in 18 decimals\n * @custom:access Only Governance\n * @custom:event Emits PricePosted event on succesfully setup of asset price\n */\n function setDirectPrice(address asset, uint256 price) external notNullAddress(asset) {\n _checkAccessAllowed(\"setDirectPrice(address,uint256)\");\n\n uint256 previousPriceMantissa = prices[asset];\n prices[asset] = price;\n emit PricePosted(asset, previousPriceMantissa, price);\n }\n\n /**\n * @notice Add multiple token configs at the same time\n * @param tokenConfigs_ config array\n * @custom:access Only Governance\n * @custom:error Zero length error thrown, if length of the array in parameter is 0\n */\n function setTokenConfigs(TokenConfig[] memory tokenConfigs_) external {\n if (tokenConfigs_.length == 0) revert(\"length can't be 0\");\n uint256 numTokenConfigs = tokenConfigs_.length;\n for (uint256 i; i < numTokenConfigs; ) {\n setTokenConfig(tokenConfigs_[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Initializes the owner of the contract\n * @param accessControlManager_ Address of the access control manager contract\n */\n function initialize(address accessControlManager_) external initializer {\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Add single token config. asset & feed cannot be null addresses and maxStalePeriod must be positive\n * @param tokenConfig Token config struct\n * @custom:access Only Governance\n * @custom:error NotNullAddress error is thrown if asset address is null\n * @custom:error NotNullAddress error is thrown if token feed address is null\n * @custom:error Range error is thrown if maxStale period of token is not greater than zero\n * @custom:event Emits TokenConfigAdded event on succesfully setting of the token config\n */\n function setTokenConfig(\n TokenConfig memory tokenConfig\n ) public notNullAddress(tokenConfig.asset) notNullAddress(tokenConfig.feed) {\n _checkAccessAllowed(\"setTokenConfig(TokenConfig)\");\n\n if (tokenConfig.maxStalePeriod == 0) revert(\"stale period can't be zero\");\n tokenConfigs[tokenConfig.asset] = tokenConfig;\n emit TokenConfigAdded(tokenConfig.asset, tokenConfig.feed, tokenConfig.maxStalePeriod);\n }\n\n /**\n * @notice Gets the price of a asset from the chainlink oracle\n * @param asset Address of the asset\n * @return Price in USD from Chainlink or a manually set price for the asset\n */\n function getPrice(address asset) public view returns (uint256) {\n uint256 decimals;\n\n if (asset == BNB_ADDR) {\n decimals = 18;\n } else {\n IERC20Metadata token = IERC20Metadata(asset);\n decimals = token.decimals();\n }\n\n return _getPriceInternal(asset, decimals);\n }\n\n /**\n * @notice Gets the Chainlink price for a given asset\n * @param asset address of the asset\n * @param decimals decimals of the asset\n * @return price Asset price in USD or a manually set price of the asset\n */\n function _getPriceInternal(address asset, uint256 decimals) internal view returns (uint256 price) {\n uint256 tokenPrice = prices[asset];\n if (tokenPrice != 0) {\n price = tokenPrice;\n } else {\n price = _getChainlinkPrice(asset);\n }\n\n uint256 decimalDelta = 18 - decimals;\n return price * (10 ** decimalDelta);\n }\n\n /**\n * @notice Get the Chainlink price for an asset, revert if token config doesn't exist\n * @dev The precision of the price feed is used to ensure the returned price has 18 decimals of precision\n * @param asset Address of the asset\n * @return price Price in USD, with 18 decimals of precision\n * @custom:error NotNullAddress error is thrown if the asset address is null\n * @custom:error Price error is thrown if the Chainlink price of asset is not greater than zero\n * @custom:error Timing error is thrown if current timestamp is less than the last updatedAt timestamp\n * @custom:error Timing error is thrown if time difference between current time and last updated time\n * is greater than maxStalePeriod\n */\n function _getChainlinkPrice(\n address asset\n ) private view notNullAddress(tokenConfigs[asset].asset) returns (uint256) {\n TokenConfig memory tokenConfig = tokenConfigs[asset];\n AggregatorV3Interface feed = AggregatorV3Interface(tokenConfig.feed);\n\n // note: maxStalePeriod cannot be 0\n uint256 maxStalePeriod = tokenConfig.maxStalePeriod;\n\n // Chainlink USD-denominated feeds store answers at 8 decimals, mostly\n uint256 decimalDelta = 18 - feed.decimals();\n\n (, int256 answer, , uint256 updatedAt, ) = feed.latestRoundData();\n if (answer <= 0) revert(\"chainlink price must be positive\");\n if (block.timestamp < updatedAt) revert(\"updatedAt exceeds block time\");\n\n uint256 deltaTime;\n unchecked {\n deltaTime = block.timestamp - updatedAt;\n }\n\n if (deltaTime > maxStalePeriod) revert(\"chainlink price expired\");\n\n return uint256(answer) * (10 ** decimalDelta);\n }\n}\n" + }, + "contracts/BaseJumpRateModelV2.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IAccessControlManagerV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\";\n\nimport { InterestRateModel } from \"./InterestRateModel.sol\";\nimport { BLOCKS_PER_YEAR, EXP_SCALE, MANTISSA_ONE } from \"./lib/constants.sol\";\n\n/**\n * @title Logic for Compound's JumpRateModel Contract V2.\n * @author Compound (modified by Dharma Labs, Arr00 and Venus)\n * @notice An interest rate model with a steep increase after a certain utilization threshold called **kink** is reached.\n * The parameters of this interest rate model can be adjusted by the owner. Version 2 modifies Version 1 by enabling updateable parameters.\n */\nabstract contract BaseJumpRateModelV2 is InterestRateModel {\n /**\n * @notice The address of the AccessControlManager contract\n */\n IAccessControlManagerV8 public accessControlManager;\n\n /**\n * @notice The multiplier of utilization rate that gives the slope of the interest rate\n */\n uint256 public multiplierPerBlock;\n\n /**\n * @notice The base interest rate which is the y-intercept when utilization rate is 0\n */\n uint256 public baseRatePerBlock;\n\n /**\n * @notice The multiplier per block after hitting a specified utilization point\n */\n uint256 public jumpMultiplierPerBlock;\n\n /**\n * @notice The utilization point at which the jump multiplier is applied\n */\n uint256 public kink;\n\n event NewInterestParams(\n uint256 baseRatePerBlock,\n uint256 multiplierPerBlock,\n uint256 jumpMultiplierPerBlock,\n uint256 kink\n );\n\n /**\n * @notice Thrown when the action is prohibited by AccessControlManager\n */\n error Unauthorized(address sender, address calledContract, string methodSignature);\n\n /**\n * @notice Construct an interest rate model\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by EXP_SCALE)\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)\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 * @param accessControlManager_ The address of the AccessControlManager contract\n */\n constructor(\n uint256 baseRatePerYear,\n uint256 multiplierPerYear,\n uint256 jumpMultiplierPerYear,\n uint256 kink_,\n IAccessControlManagerV8 accessControlManager_\n ) {\n require(address(accessControlManager_) != address(0), \"invalid ACM address\");\n\n accessControlManager = accessControlManager_;\n\n _updateJumpRateModel(baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_);\n }\n\n /**\n * @notice Update the parameters of the interest rate model\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by EXP_SCALE)\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)\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 * @custom:error Unauthorized if the sender is not allowed to call this function\n * @custom:access Controlled by AccessControlManager\n */\n function updateJumpRateModel(\n uint256 baseRatePerYear,\n uint256 multiplierPerYear,\n uint256 jumpMultiplierPerYear,\n uint256 kink_\n ) external virtual {\n string memory signature = \"updateJumpRateModel(uint256,uint256,uint256,uint256)\";\n bool isAllowedToCall = accessControlManager.isAllowedToCall(msg.sender, signature);\n\n if (!isAllowedToCall) {\n revert Unauthorized(msg.sender, address(this), signature);\n }\n\n _updateJumpRateModel(baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_);\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 * @param badDebt The amount of badDebt in the market\n * @return The supply rate percentage per block as a mantissa (scaled by EXP_SCALE)\n */\n function getSupplyRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 reserveFactorMantissa,\n uint256 badDebt\n ) public view virtual override returns (uint256) {\n uint256 oneMinusReserveFactor = MANTISSA_ONE - reserveFactorMantissa;\n uint256 borrowRate = _getBorrowRate(cash, borrows, reserves, badDebt);\n uint256 rateToPool = (borrowRate * oneMinusReserveFactor) / EXP_SCALE;\n uint256 incomeToDistribute = borrows * rateToPool;\n uint256 supply = cash + borrows + badDebt - reserves;\n return incomeToDistribute / supply;\n }\n\n /**\n * @notice Calculates the utilization rate of the market: `(borrows + badDebt) / (cash + borrows + badDebt - 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 * @param badDebt The amount of badDebt in the market\n * @return The utilization rate as a mantissa between [0, MANTISSA_ONE]\n */\n function utilizationRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) public pure returns (uint256) {\n // Utilization rate is 0 when there are no borrows and badDebt\n if ((borrows + badDebt) == 0) {\n return 0;\n }\n\n uint256 rate = ((borrows + badDebt) * EXP_SCALE) / (cash + borrows + badDebt - reserves);\n\n if (rate > EXP_SCALE) {\n rate = EXP_SCALE;\n }\n\n return rate;\n }\n\n /**\n * @notice Internal function to update the parameters of the interest rate model\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by EXP_SCALE)\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)\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 function _updateJumpRateModel(\n uint256 baseRatePerYear,\n uint256 multiplierPerYear,\n uint256 jumpMultiplierPerYear,\n uint256 kink_\n ) internal {\n baseRatePerBlock = baseRatePerYear / BLOCKS_PER_YEAR;\n multiplierPerBlock = multiplierPerYear / BLOCKS_PER_YEAR;\n jumpMultiplierPerBlock = jumpMultiplierPerYear / BLOCKS_PER_YEAR;\n kink = kink_;\n\n emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink);\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 * @param badDebt The amount of badDebt in the market\n * @return The borrow rate percentage per block as a mantissa (scaled by EXP_SCALE)\n */\n function _getBorrowRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) internal view returns (uint256) {\n uint256 util = utilizationRate(cash, borrows, reserves, badDebt);\n uint256 kink_ = kink;\n\n if (util <= kink_) {\n return ((util * multiplierPerBlock) / EXP_SCALE) + baseRatePerBlock;\n }\n uint256 normalRate = ((kink_ * multiplierPerBlock) / EXP_SCALE) + baseRatePerBlock;\n uint256 excessUtil;\n unchecked {\n excessUtil = util - kink_;\n }\n return ((excessUtil * jumpMultiplierPerBlock) / EXP_SCALE) + normalRate;\n }\n}\n" + }, + "contracts/Comptroller.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { ComptrollerInterface } from \"./ComptrollerInterface.sol\";\nimport { ComptrollerStorage } from \"./ComptrollerStorage.sol\";\nimport { ExponentialNoError } from \"./ExponentialNoError.sol\";\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\nimport { MaxLoopsLimitHelper } from \"./MaxLoopsLimitHelper.sol\";\nimport { ensureNonzeroAddress } from \"./lib/validators.sol\";\n\n/**\n * @title Comptroller\n * @author Venus\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market’s corresponding liquidation threshold,\n * the borrow is eligible for liquidation.\n *\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\n * the `minLiquidatableCollateral` for the `Comptroller`:\n *\n * - `healAccount()`: This function is called to seize all of a given user’s collateral, requiring the `msg.sender` repay a certain percentage\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\n * verifying that the repay amount does not exceed the close factor.\n */\ncontract Comptroller is\n Ownable2StepUpgradeable,\n AccessControlledV8,\n ComptrollerStorage,\n ComptrollerInterface,\n ExponentialNoError,\n MaxLoopsLimitHelper\n{\n // PoolRegistry, immutable to save on gas\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n address public immutable poolRegistry;\n\n /// @notice Emitted when an account enters a market\n event MarketEntered(VToken indexed vToken, address indexed account);\n\n /// @notice Emitted when an account exits a market\n event MarketExited(VToken indexed vToken, address indexed account);\n\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\n\n /// @notice Emitted when liquidation threshold is changed by admin\n event NewLiquidationThreshold(\n VToken vToken,\n uint256 oldLiquidationThresholdMantissa,\n uint256 newLiquidationThresholdMantissa\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\n\n /// @notice Emitted when an action is paused on a market\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\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 the collateral threshold (in USD) for non-batch liquidations is changed\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\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 a rewards distributor is added\n event NewRewardsDistributor(address indexed rewardsDistributor);\n\n /// @notice Emitted when a market is supported\n event MarketSupported(VToken vToken);\n\n /// @notice Thrown when collateral factor exceeds the upper bound\n error InvalidCollateralFactor();\n\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\n error InvalidLiquidationThreshold();\n\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\n error UnexpectedSender(address expectedSender, address actualSender);\n\n /// @notice Thrown when the oracle returns an invalid price for some asset\n error PriceError(address vToken);\n\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\n error SnapshotError(address vToken, address user);\n\n /// @notice Thrown when the market is not listed\n error MarketNotListed(address market);\n\n /// @notice Thrown when a market has an unexpected comptroller\n error ComptrollerMismatch();\n\n /// @notice Thrown when user is not member of market\n error MarketNotCollateral(address vToken, address user);\n\n /**\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\n * or healAccount) are available.\n */\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\n\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\n error InsufficientLiquidity();\n\n /// @notice Thrown when trying to liquidate a healthy account\n error InsufficientShortfall();\n\n /// @notice Thrown when trying to repay more than allowed by close factor\n error TooMuchRepay();\n\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\n error NonzeroBorrowBalance();\n\n /// @notice Thrown when trying to perform an action that is paused\n error ActionPaused(address market, Action action);\n\n /// @notice Thrown when trying to add a market that is already listed\n error MarketAlreadyListed(address market);\n\n /// @notice Thrown if the supply cap is exceeded\n error SupplyCapExceeded(address market, uint256 cap);\n\n /// @notice Thrown if the borrow cap is exceeded\n error BorrowCapExceeded(address market, uint256 cap);\n\n /// @param poolRegistry_ Pool registry address\n /// @custom:oz-upgrades-unsafe-allow constructor\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n constructor(address poolRegistry_) {\n ensureNonzeroAddress(poolRegistry_);\n\n poolRegistry = poolRegistry_;\n _disableInitializers();\n }\n\n /**\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\n * @param accessControlManager Access control manager contract address\n */\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager);\n\n _setMaxLoopsLimit(loopLimit);\n }\n\n /**\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\n * @param vTokens The list of addresses of the vToken markets to be enabled\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\n * @custom:event MarketEntered is emitted for each market on success\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\n * @custom:access Not restricted\n */\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\n uint256 len = vTokens.length;\n\n uint256[] memory results = new uint256[](len);\n for (uint256 i; i < len; ++i) {\n VToken vToken = VToken(vTokens[i]);\n\n _addToMarket(vToken, msg.sender);\n results[i] = NO_ERROR;\n }\n\n return results;\n }\n\n /**\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event MarketExited is emitted on success\n * @custom:error ActionPaused error is thrown if exiting the market is paused\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function exitMarket(address vTokenAddress) external override returns (uint256) {\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\n VToken vToken = VToken(vTokenAddress);\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\n\n /* Fail if the sender has a borrow balance */\n if (amountOwed != 0) {\n revert NonzeroBorrowBalance();\n }\n\n /* Fail if the sender is not permitted to redeem all of their tokens */\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\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 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 // load into memory for faster iteration\n VToken[] memory userAssetList = accountAssets[msg.sender];\n uint256 len = userAssetList.length;\n\n uint256 assetIndex = len;\n for (uint256 i; i < len; ++i) {\n if (userAssetList[i] == vToken) {\n assetIndex = i;\n break;\n }\n }\n\n // We *must* have found the asset in the list or our redundant data structure is broken\n assert(assetIndex < len);\n\n // copy last item in list to location of item to be removed, reduce length by 1\n VToken[] storage storedList = accountAssets[msg.sender];\n storedList[assetIndex] = storedList[storedList.length - 1];\n storedList.pop();\n\n emit MarketExited(vToken, msg.sender);\n\n return NO_ERROR;\n }\n\n /*** Policy Hooks ***/\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\n * @custom:access Not restricted\n */\n function preMintHook(\n address vToken,\n address minter,\n uint256 mintAmount\n ) external override {\n _checkActionPauseState(vToken, Action.MINT);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n uint256 supplyCap = supplyCaps[vToken];\n // Skipping the cap check for uncapped coins to save some gas\n if (supplyCap != type(uint256).max) {\n uint256 vTokenSupply = VToken(vToken).totalSupply();\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\n if (nextTotalSupply > supplyCap) {\n revert SupplyCapExceeded(vToken, supplyCap);\n }\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function preRedeemHook(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) external override {\n _checkActionPauseState(vToken, Action.REDEEM);\n\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\n */\n /// disable-eslint\n function preBorrowHook(\n address vToken,\n address borrower,\n uint256 borrowAmount\n ) external override {\n _checkActionPauseState(vToken, Action.BORROW);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n if (!markets[vToken].accountMembership[borrower]) {\n // only vTokens may call borrowAllowed if borrower not in market\n _checkSenderIs(vToken);\n\n // attempt to add borrower to the market or revert\n _addToMarket(VToken(msg.sender), borrower);\n }\n\n // Update the prices of tokens\n updatePrices(borrower);\n\n if (oracle.getUnderlyingPrice(vToken) == 0) {\n revert PriceError(address(vToken));\n }\n\n uint256 borrowCap = borrowCaps[vToken];\n // Skipping the cap check for uncapped coins to save some gas\n if (borrowCap != type(uint256).max) {\n uint256 totalBorrows = VToken(vToken).totalBorrows();\n uint256 nextTotalBorrows = totalBorrows + borrowAmount;\n if (nextTotalBorrows > borrowCap) {\n revert BorrowCapExceeded(vToken, borrowCap);\n }\n }\n\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n borrower,\n VToken(vToken),\n 0,\n borrowAmount,\n _getCollateralFactor\n );\n\n if (snapshot.shortfall > 0) {\n revert InsufficientLiquidity();\n }\n\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\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 borrower The account which would borrowed the asset\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:access Not restricted\n */\n function preRepayHook(address vToken, address borrower) external override {\n _checkActionPauseState(vToken, Action.REPAY);\n\n oracle.updatePrice(vToken);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\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 borrower The address of the borrower\n * @param repayAmount The amount of underlying being repaid\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n */\n function preLiquidateHook(\n address vTokenBorrowed,\n address vTokenCollateral,\n address borrower,\n uint256 repayAmount,\n bool skipLiquidityCheck\n ) external override {\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\n // If we want to pause liquidating to vTokenCollateral, we should pause\n // Action.SEIZE on it\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\n\n // Update the prices of tokens\n updatePrices(borrower);\n\n if (!markets[vTokenBorrowed].isListed) {\n revert MarketNotListed(address(vTokenBorrowed));\n }\n if (!markets[vTokenCollateral].isListed) {\n revert MarketNotListed(address(vTokenCollateral));\n }\n\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\n\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\n if (repayAmount > borrowBalance) {\n revert TooMuchRepay();\n }\n return;\n }\n\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\n /* The liquidator should use either liquidateAccount or healAccount */\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n /* The liquidator may not repay more than what is allowed by the closeFactor */\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\n if (repayAmount > maxClose) {\n revert TooMuchRepay();\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\n * @custom:access Not restricted\n */\n function preSeizeHook(\n address vTokenCollateral,\n address seizerContract,\n address liquidator,\n address borrower\n ) external override {\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\n // If we want to pause liquidating vTokenBorrowed, we should pause\n // Action.LIQUIDATE on it\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\n\n Market storage market = markets[vTokenCollateral];\n\n if (!market.isListed) {\n revert MarketNotListed(vTokenCollateral);\n }\n\n if (seizerContract == address(this)) {\n // If Comptroller is the seizer, just check if collateral's comptroller\n // is equal to the current address\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\n revert ComptrollerMismatch();\n }\n } else {\n // If the seizer is not the Comptroller, check that the seizer is a\n // listed market, and that the markets' comptrollers match\n if (!markets[seizerContract].isListed) {\n revert MarketNotListed(seizerContract);\n }\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\n revert ComptrollerMismatch();\n }\n }\n\n if (!market.accountMembership[borrower]) {\n revert MarketNotCollateral(vTokenCollateral, borrower);\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function preTransferHook(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external override {\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 _checkRedeemAllowed(vToken, src, transferTokens);\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\n }\n }\n\n /*** Pool-level operations ***/\n\n /**\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\n * borrows, and treats the rest of the debt as bad debt (for each market).\n * The sender has to repay a certain percentage of the debt, computed as\n * collateral / (borrows * liquidationIncentive).\n * @param user account to heal\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function healAccount(address user) external {\n VToken[] memory userAssets = accountAssets[user];\n uint256 userAssetsCount = userAssets.length;\n\n address liquidator = msg.sender;\n {\n ResilientOracleInterface oracle_ = oracle;\n // We need all user's markets to be fresh for the computations to be correct\n for (uint256 i; i < userAssetsCount; ++i) {\n userAssets[i].accrueInterest();\n oracle_.updatePrice(address(userAssets[i]));\n }\n }\n\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n // percentage = collateral / (borrows * liquidation incentive)\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\n Exp memory scaledBorrows = mul_(\n Exp({ mantissa: snapshot.borrows }),\n Exp({ mantissa: liquidationIncentiveMantissa })\n );\n\n Exp memory percentage = div_(collateral, scaledBorrows);\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\n }\n\n for (uint256 i; i < userAssetsCount; ++i) {\n VToken market = userAssets[i];\n\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\n\n // Seize the entire collateral\n if (tokens != 0) {\n market.seize(liquidator, user, tokens);\n }\n // Repay a certain percentage of the borrow, forgive the rest\n if (borrowBalance != 0) {\n market.healBorrow(liquidator, user, repaymentAmount);\n }\n }\n }\n\n /**\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\n * below the threshold, and the account is insolvent, use healAccount.\n * @param borrower the borrower address\n * @param orders an array of liquidation orders\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\n // We will accrue interest and update the oracle prices later during the liquidation\n\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\n // You should use the regular vToken.liquidateBorrow(...) call\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n uint256 collateralToSeize = mul_ScalarTruncate(\n Exp({ mantissa: liquidationIncentiveMantissa }),\n snapshot.borrows\n );\n if (collateralToSeize >= snapshot.totalCollateral) {\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\n // and record bad debt.\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n uint256 ordersCount = orders.length;\n\n _ensureMaxLoops(ordersCount / 2);\n\n for (uint256 i; i < ordersCount; ++i) {\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\n }\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\n revert MarketNotListed(address(orders[i].vTokenCollateral));\n }\n\n LiquidationOrder calldata order = orders[i];\n order.vTokenBorrowed.forceLiquidateBorrow(\n msg.sender,\n borrower,\n order.repayAmount,\n order.vTokenCollateral,\n true\n );\n }\n\n VToken[] memory borrowMarkets = accountAssets[borrower];\n uint256 marketsCount = borrowMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\n require(borrowBalance == 0, \"Nonzero borrow balance after liquidation\");\n }\n }\n\n /**\n * @notice Sets the closeFactor to use when liquidating borrows\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\n * @custom:event Emits NewCloseFactor on success\n * @custom:access Controlled by AccessControlManager\n */\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\n _checkAccessAllowed(\"setCloseFactor(uint256)\");\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \"Close factor greater than maximum close factor\");\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \"Close factor smaller than minimum close factor\");\n\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\n closeFactorMantissa = newCloseFactorMantissa;\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\n }\n\n /**\n * @notice Sets the collateralFactor for a market\n * @dev This function is restricted by the AccessControlManager\n * @param vToken The market to set the factor on\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\n * and NewLiquidationThreshold when liquidation threshold is updated\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\n * @custom:access Controlled by AccessControlManager\n */\n function setCollateralFactor(\n VToken vToken,\n uint256 newCollateralFactorMantissa,\n uint256 newLiquidationThresholdMantissa\n ) external {\n _checkAccessAllowed(\"setCollateralFactor(address,uint256,uint256)\");\n\n // Verify market is listed\n Market storage market = markets[address(vToken)];\n if (!market.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n // Check collateral factor <= 0.9\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\n revert InvalidCollateralFactor();\n }\n\n // Ensure that liquidation threshold <= 1\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\n revert InvalidLiquidationThreshold();\n }\n\n // Ensure that liquidation threshold >= CF\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\n revert InvalidLiquidationThreshold();\n }\n\n // If collateral factor != 0, fail if price == 0\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\n revert PriceError(address(vToken));\n }\n\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\n market.collateralFactorMantissa = newCollateralFactorMantissa;\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\n }\n\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\n }\n }\n\n /**\n * @notice Sets liquidationIncentive\n * @dev This function is restricted by the AccessControlManager\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\n * @custom:event Emits NewLiquidationIncentive on success\n * @custom:access Controlled by AccessControlManager\n */\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \"liquidation incentive should be greater than 1e18\");\n\n _checkAccessAllowed(\"setLiquidationIncentive(uint256)\");\n\n // Save current value for use in log\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\n\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\n /**\n * @notice Add the market to the markets mapping and set it as listed\n * @dev Only callable by the PoolRegistry\n * @param vToken The address of the market (token) to list\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\n * @custom:access Only PoolRegistry\n */\n function supportMarket(VToken vToken) external {\n _checkSenderIs(poolRegistry);\n\n if (markets[address(vToken)].isListed) {\n revert MarketAlreadyListed(address(vToken));\n }\n\n require(vToken.isVToken(), \"Comptroller: Invalid vToken\"); // Sanity check to make sure its really a VToken\n\n Market storage newMarket = markets[address(vToken)];\n newMarket.isListed = true;\n newMarket.collateralFactorMantissa = 0;\n newMarket.liquidationThresholdMantissa = 0;\n\n _addMarket(address(vToken));\n\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n rewardsDistributors[i].initializeMarket(address(vToken));\n }\n\n emit MarketSupported(vToken);\n }\n\n /**\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\n * @dev This function is restricted by the AccessControlManager\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\n until the total borrows amount goes below the new borrow cap\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 type(uint256).max corresponds to unlimited borrowing.\n * @custom:access Controlled by AccessControlManager\n */\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\n _checkAccessAllowed(\"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 _ensureMaxLoops(numMarkets);\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 markets. Supply that brings total Supply to or above supply cap will revert.\n * @dev This function is restricted by the AccessControlManager\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\n until the total supplies amount goes below the new supply cap\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 type(uint256).max corresponds to unlimited supply.\n * @custom:access Controlled by AccessControlManager\n */\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\n _checkAccessAllowed(\"setMarketSupplyCaps(address[],uint256[])\");\n uint256 vTokensCount = vTokens.length;\n\n require(vTokensCount != 0, \"invalid number of markets\");\n require(vTokensCount == newSupplyCaps.length, \"invalid number of markets\");\n\n _ensureMaxLoops(vTokensCount);\n\n for (uint256 i; i < vTokensCount; ++i) {\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\n }\n }\n\n /**\n * @notice Pause/unpause specified actions\n * @dev This function is restricted by the AccessControlManager\n * @param marketsList Markets to pause/unpause the actions on\n * @param actionsList List of action ids to pause/unpause\n * @param paused The new paused state (true=paused, false=unpaused)\n * @custom:access Controlled by AccessControlManager\n */\n function setActionsPaused(\n VToken[] calldata marketsList,\n Action[] calldata actionsList,\n bool paused\n ) external {\n _checkAccessAllowed(\"setActionsPaused(address[],uint256[],bool)\");\n\n uint256 marketsCount = marketsList.length;\n uint256 actionsCount = actionsList.length;\n\n _ensureMaxLoops(marketsCount * actionsCount);\n\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\n }\n }\n }\n\n /**\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\n * operations like liquidateAccount or healAccount.\n * @dev This function is restricted by the AccessControlManager\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\n * @custom:access Controlled by AccessControlManager\n */\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\n _checkAccessAllowed(\"setMinLiquidatableCollateral(uint256)\");\n\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\n minLiquidatableCollateral = newMinLiquidatableCollateral;\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\n }\n\n /**\n * @notice Add a new RewardsDistributor and initialize it with all markets\n * @dev Only callable by the admin\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\n * @custom:access Only Governance\n * @custom:event Emits NewRewardsDistributor with distributor address\n */\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \"already exists\");\n\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\n\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\n address rewardToken = address(rewardsDistributors[i].rewardToken());\n require(\n rewardToken != address(_rewardsDistributor.rewardToken()),\n \"distributor already exists with this reward\"\n );\n }\n\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\n _ensureMaxLoops(rewardsDistributorsLen + 1);\n\n rewardsDistributors.push(_rewardsDistributor);\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\n\n uint256 marketsCount = allMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\n }\n\n emit NewRewardsDistributor(address(_rewardsDistributor));\n }\n\n /**\n * @notice Sets a new price oracle for the Comptroller\n * @dev Only callable by the admin\n * @param newOracle Address of the new price oracle to set\n * @custom:event Emits NewPriceOracle on success\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\n */\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\n ensureNonzeroAddress(address(newOracle));\n\n ResilientOracleInterface oldOracle = oracle;\n oracle = newOracle;\n emit NewPriceOracle(oldOracle, newOracle);\n }\n\n /**\n * @notice Set the for loop iteration limit to avoid DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\n * @param account The account get liquidity for\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\n * @return shortfall Account shortfall below liquidation threshold requirements\n */\n function getAccountLiquidity(address account)\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\n }\n\n /**\n * @notice Determine the current account liquidity with respect to collateral requirements\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\n * @param account The account get liquidity for\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Account liquidity in excess of collateral requirements,\n * @return shortfall Account shortfall below collateral requirements\n */\n function getBorrowingPower(address account)\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\n }\n\n /**\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\n * @return shortfall Hypothetical account shortfall below collateral requirements\n */\n function getHypotheticalAccountLiquidity(\n address account,\n address vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n )\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n account,\n VToken(vTokenModify),\n redeemTokens,\n borrowAmount,\n _getCollateralFactor\n );\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\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 markets The list of market addresses\n */\n function getAllMarkets() external view override returns (VToken[] memory) {\n return allMarkets;\n }\n\n /**\n * @notice Check if a market is marked as listed (active)\n * @param vToken vToken Address for the market to check\n * @return listed True if listed otherwise false\n */\n function isMarketListed(VToken vToken) external view returns (bool) {\n return markets[address(vToken)].isListed;\n }\n\n /*** Assets You Are In ***/\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 list with the assets the account has entered\n */\n function getAssetsIn(address account) external view returns (VToken[] memory) {\n VToken[] memory assetsIn = accountAssets[account];\n\n return assetsIn;\n }\n\n /**\n * @notice Returns whether the given account is entered in a given market\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\n * @custom:error PriceError if the oracle returns an invalid price\n */\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\n /* Read oracle prices for borrowed and collateral markets */\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\n uint256 seizeTokens;\n Exp memory numerator;\n Exp memory denominator;\n Exp memory ratio;\n\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\n ratio = div_(numerator, denominator);\n\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\n\n return (NO_ERROR, seizeTokens);\n }\n\n /**\n * @notice Returns reward speed given a vToken\n * @param vToken The vToken to get the reward speeds for\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\n */\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n address rewardToken = address(rewardsDistributor.rewardToken());\n rewardSpeeds[i] = RewardSpeeds({\n rewardToken: rewardToken,\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\n });\n }\n return rewardSpeeds;\n }\n\n /**\n * @notice Return all reward distributors for this pool\n * @return Array of RewardDistributor addresses\n */\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\n return rewardsDistributors;\n }\n\n /**\n * @notice A marker method that returns true for a valid Comptroller contract\n * @return Always true\n */\n function isComptroller() external pure override returns (bool) {\n return true;\n }\n\n /**\n * @notice Update the prices of all the tokens associated with the provided account\n * @param account Address of the account to get associated tokens with\n */\n function updatePrices(address account) public {\n VToken[] memory vTokens = accountAssets[account];\n uint256 vTokensCount = vTokens.length;\n\n ResilientOracleInterface oracle_ = oracle;\n\n for (uint256 i; i < vTokensCount; ++i) {\n oracle_.updatePrice(address(vTokens[i]));\n }\n }\n\n /**\n * @notice Checks if a certain action is paused on a market\n * @param market vToken address\n * @param action Action to check\n * @return paused True if the action is paused otherwise false\n */\n function actionPaused(address market, Action action) public view returns (bool) {\n return _actionPaused[market][action];\n }\n\n /**\n * @notice Check if a vToken market has been deprecated\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\n * @param vToken The market to check if deprecated\n * @return deprecated True if the given vToken market has been deprecated\n */\n function isDeprecated(VToken vToken) public view returns (bool) {\n return\n markets[address(vToken)].collateralFactorMantissa == 0 &&\n actionPaused(address(vToken), Action.BORROW) &&\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\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 */\n function _addToMarket(VToken vToken, address borrower) internal {\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\n Market storage marketToJoin = markets[address(vToken)];\n\n if (!marketToJoin.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n if (marketToJoin.accountMembership[borrower]) {\n // already joined\n return;\n }\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\n /**\n * @notice Internal function to validate that a market hasn't already been added\n * and if it hasn't adds it\n * @param vToken The market to support\n */\n function _addMarket(address vToken) internal {\n uint256 marketsCount = allMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n if (allMarkets[i] == VToken(vToken)) {\n revert MarketAlreadyListed(vToken);\n }\n }\n allMarkets.push(VToken(vToken));\n marketsCount = allMarkets.length;\n _ensureMaxLoops(marketsCount);\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 _setActionPaused(\n address market,\n Action action,\n bool paused\n ) internal {\n require(markets[market].isListed, \"cannot pause a market that is not listed\");\n _actionPaused[market][action] = paused;\n emit ActionPausedMarket(VToken(market), action, paused);\n }\n\n /**\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\n * @param vToken Address of the vTokens to redeem\n * @param redeemer Account redeeming the tokens\n * @param redeemTokens The number of tokens to redeem\n */\n function _checkRedeemAllowed(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) internal {\n Market storage market = markets[vToken];\n\n if (!market.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\n if (!market.accountMembership[redeemer]) {\n return;\n }\n\n // Update the prices of tokens\n updatePrices(redeemer);\n\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n redeemer,\n VToken(vToken),\n redeemTokens,\n 0,\n _getCollateralFactor\n );\n if (snapshot.shortfall > 0) {\n revert InsufficientLiquidity();\n }\n }\n\n /**\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\n * @param account The account to get the snapshot for\n * @param weight The function to compute the weight of the collateral – either collateral factor or\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\n * without calculating accumulated interest.\n * @return snapshot Account liquidity snapshot\n */\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\n internal\n view\n returns (AccountLiquiditySnapshot memory snapshot)\n {\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\n }\n\n /**\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral – either collateral factor or\n liquidation threshold. Accepts the address of the VToken and returns the weight\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\n * without calculating accumulated interest.\n * @return snapshot Account liquidity snapshot\n */\n function _getHypotheticalLiquiditySnapshot(\n address account,\n VToken vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount,\n function(VToken) internal view returns (Exp memory) weight\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\n // For each asset the account is in\n VToken[] memory assets = accountAssets[account];\n uint256 assetsCount = assets.length;\n\n for (uint256 i; i < assetsCount; ++i) {\n VToken asset = assets[i];\n\n // Read the balances and exchange rate from the vToken\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\n asset,\n account\n );\n\n // Get the normalized price of the asset\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\n\n // Pre-compute conversion factors from vTokens -> usd\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\n\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\n weightedVTokenPrice,\n vTokenBalance,\n snapshot.weightedCollateral\n );\n\n // totalCollateral += vTokenPrice * vTokenBalance\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\n\n // borrows += oraclePrice * borrowBalance\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\n\n // Calculate effects of interacting with vTokenModify\n if (asset == vTokenModify) {\n // redeem effect\n // effects += tokensToDenom * redeemTokens\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\n\n // borrow effect\n // effects += oraclePrice * borrowAmount\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\n }\n }\n\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\n // These are safe, as the underflow condition is checked first\n unchecked {\n if (snapshot.weightedCollateral > borrowPlusEffects) {\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\n snapshot.shortfall = 0;\n } else {\n snapshot.liquidity = 0;\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\n }\n }\n\n return snapshot;\n }\n\n /**\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\n * @param asset Address for asset to query price\n * @return Underlying price\n */\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\n if (oraclePriceMantissa == 0) {\n revert PriceError(address(asset));\n }\n return oraclePriceMantissa;\n }\n\n /**\n * @dev Return collateral factor for a market\n * @param asset Address for asset\n * @return Collateral factor as exponential\n */\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\n }\n\n /**\n * @dev Retrieves liquidation threshold for a market as an exponential\n * @param asset Address for asset to liquidation threshold\n * @return Liquidation threshold as exponential\n */\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\n }\n\n /**\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\n * @param vToken Market to query\n * @param user Account address\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\n * @return borrowBalance Borrowed amount, including the interest\n * @return exchangeRateMantissa Stored exchange rate\n */\n function _safeGetAccountSnapshot(VToken vToken, address user)\n internal\n view\n returns (\n uint256 vTokenBalance,\n uint256 borrowBalance,\n uint256 exchangeRateMantissa\n )\n {\n uint256 err;\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\n if (err != 0) {\n revert SnapshotError(address(vToken), user);\n }\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\n }\n\n /// @notice Reverts if the call is not from expectedSender\n /// @param expectedSender Expected transaction sender\n function _checkSenderIs(address expectedSender) internal view {\n if (msg.sender != expectedSender) {\n revert UnexpectedSender(expectedSender, msg.sender);\n }\n }\n\n /// @notice Reverts if a certain action is paused on a market\n /// @param market Market to check\n /// @param action Action to check\n function _checkActionPauseState(address market, Action action) private view {\n if (actionPaused(market, action)) {\n revert ActionPaused(market, action);\n }\n }\n}\n" + }, + "contracts/ComptrollerInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\n\n/**\n * @title ComptrollerInterface\n * @author Venus\n * @notice Interface implemented by the `Comptroller` contract.\n */\ninterface ComptrollerInterface {\n /*** Assets You Are In ***/\n\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\n\n function exitMarket(address vToken) external returns (uint256);\n\n /*** Policy Hooks ***/\n\n function preMintHook(\n address vToken,\n address minter,\n uint256 mintAmount\n ) external;\n\n function preRedeemHook(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) external;\n\n function preBorrowHook(\n address vToken,\n address borrower,\n uint256 borrowAmount\n ) external;\n\n function preRepayHook(address vToken, address borrower) external;\n\n function preLiquidateHook(\n address vTokenBorrowed,\n address vTokenCollateral,\n address borrower,\n uint256 repayAmount,\n bool skipLiquidityCheck\n ) external;\n\n function preSeizeHook(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower\n ) external;\n\n function preTransferHook(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external;\n\n function isComptroller() external view returns (bool);\n\n /*** Liquidity/Liquidation Calculations ***/\n\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 repayAmount\n ) external view returns (uint256, uint256);\n\n function getAllMarkets() external view returns (VToken[] memory);\n}\n\n/**\n * @title ComptrollerViewInterface\n * @author Venus\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\n */\ninterface ComptrollerViewInterface {\n function markets(address) external view returns (bool, uint256);\n\n function oracle() external view returns (ResilientOracleInterface);\n\n function getAssetsIn(address) external view returns (VToken[] memory);\n\n function closeFactorMantissa() external view returns (uint256);\n\n function liquidationIncentiveMantissa() external view returns (uint256);\n\n function minLiquidatableCollateral() external view returns (uint256);\n\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\n\n function getAllMarkets() external view returns (VToken[] memory);\n\n function borrowCaps(address) external view returns (uint256);\n\n function supplyCaps(address) external view returns (uint256);\n}\n" + }, + "contracts/ComptrollerStorage.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\n\n/**\n * @title ComptrollerStorage\n * @author Venus\n * @notice Storage layout for the `Comptroller` contract.\n */\ncontract ComptrollerStorage {\n struct LiquidationOrder {\n VToken vTokenCollateral;\n VToken vTokenBorrowed;\n uint256 repayAmount;\n }\n\n struct AccountLiquiditySnapshot {\n uint256 totalCollateral;\n uint256 weightedCollateral;\n uint256 borrows;\n uint256 effects;\n uint256 liquidity;\n uint256 shortfall;\n }\n\n struct RewardSpeeds {\n address rewardToken;\n uint256 supplySpeed;\n uint256 borrowSpeed;\n }\n\n struct Market {\n // Whether or not this market is listed\n bool isListed;\n // 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 uint256 collateralFactorMantissa;\n // Multiplier representing the collateralization after which the borrow is eligible\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\n // value. Must be between 0 and collateral factor, stored as a mantissa.\n uint256 liquidationThresholdMantissa;\n // Per-market mapping of \"accounts in this asset\"\n mapping(address => bool) accountMembership;\n }\n\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 /**\n * @notice Oracle which gives the price of any given asset\n */\n ResilientOracleInterface 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 Per-account mapping of \"assets you are in\"\n */\n mapping(address => VToken[]) public accountAssets;\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 /// @notice A list of all markets\n VToken[] public allMarkets;\n\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\n mapping(address => uint256) public borrowCaps;\n\n /// @notice Minimal collateral required for regular (non-batch) liquidations\n uint256 public minLiquidatableCollateral;\n\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\n mapping(address => uint256) public supplyCaps;\n\n /// @notice True if a certain action is paused on a certain market\n mapping(address => mapping(Action => bool)) internal _actionPaused;\n\n // List of Reward Distributors added\n RewardsDistributor[] internal rewardsDistributors;\n\n // Used to check if rewards distributor is added\n mapping(address => bool) internal rewardsDistributorExists;\n\n uint256 internal constant NO_ERROR = 0;\n\n // closeFactorMantissa must be strictly greater than this value\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\n\n // closeFactorMantissa must not exceed this value\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\n\n // No collateralFactorMantissa may exceed this value\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\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[50] private __gap;\n}\n" + }, + "contracts/ErrorReporter.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title TokenErrorReporter\n * @author Venus\n * @notice Errors that can be thrown by the `VToken` contract.\n */\ncontract TokenErrorReporter {\n uint256 public constant NO_ERROR = 0; // support legacy return codes\n\n error TransferNotAllowed();\n\n error MintFreshnessCheck();\n\n error RedeemFreshnessCheck();\n error RedeemTransferOutNotPossible();\n\n error BorrowFreshnessCheck();\n error BorrowCashNotAvailable();\n\n error RepayBorrowFreshnessCheck();\n\n error HealBorrowUnauthorized();\n error ForceLiquidateBorrowUnauthorized();\n\n error LiquidateFreshnessCheck();\n error LiquidateCollateralFreshnessCheck();\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\n error LiquidateLiquidatorIsBorrower();\n error LiquidateCloseAmountIsZero();\n error LiquidateCloseAmountIsUintMax();\n\n error LiquidateSeizeLiquidatorIsBorrower();\n\n error ProtocolSeizeShareTooBig();\n\n error SetReserveFactorFreshCheck();\n error SetReserveFactorBoundsCheck();\n\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\n\n error ReduceReservesFreshCheck();\n error ReduceReservesCashNotAvailable();\n error ReduceReservesCashValidation();\n\n error SetInterestRateModelFreshCheck();\n}\n" + }, + "contracts/ExponentialNoError.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \"./lib/constants.sol\";\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 struct Exp {\n uint256 mantissa;\n }\n\n struct Double {\n uint256 mantissa;\n }\n\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\n uint256 internal constant DOUBLE_SCALE = 1e36;\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\n\n /**\n * @dev Truncates the given exp to a whole number value.\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\n */\n function truncate(Exp memory exp) internal pure returns (uint256) {\n // Note: We are not using careful math here as we're performing a division that cannot fail\n return exp.mantissa / EXP_SCALE;\n }\n\n /**\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\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 // solhint-disable-next-line func-name-mixedcase\n function mul_ScalarTruncateAddUInt(\n Exp memory a,\n uint256 scalar,\n uint256 addend\n ) internal pure returns (uint256) {\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\n require(n <= type(uint224).max, errorMessage);\n return uint224(n);\n }\n\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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_(uint256 a, uint256 b) internal pure returns (uint256) {\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) / EXP_SCALE });\n }\n\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\n return mul_(a, b.mantissa) / EXP_SCALE;\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) / DOUBLE_SCALE });\n }\n\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\n }\n\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\n }\n\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\n }\n\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\n }\n\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\n }\n}\n" + }, + "contracts/InterestRateModel.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title Compound's InterestRateModel Interface\n * @author Compound\n */\nabstract contract InterestRateModel {\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 amount of reserves the market has\n * @param badDebt The amount of badDebt in the market\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\n */\n function getBorrowRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) external view virtual returns (uint256);\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 amount of reserves the market has\n * @param reserveFactorMantissa The current reserve factor the market has\n * @param badDebt The amount of badDebt in the market\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\n */\n function getSupplyRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 reserveFactorMantissa,\n uint256 badDebt\n ) external view virtual returns (uint256);\n\n /**\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\n * @return Always true\n */\n function isInterestRateModel() external pure virtual returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/IPancakeswapV2Router.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface IPancakeswapV2Router {\n function swapExactTokensForTokens(\n uint256 amountIn,\n uint256 amountOutMin,\n address[] calldata path,\n address to,\n uint256 deadline\n ) external returns (uint256[] memory amounts);\n}\n" + }, + "contracts/JumpRateModelV2.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IAccessControlManagerV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\";\n\nimport { BaseJumpRateModelV2 } from \"./BaseJumpRateModelV2.sol\";\n\n/**\n * @title Compound's JumpRateModel Contract V2 for V2 vTokens\n * @author Arr00\n * @notice Supports only for V2 vTokens\n */\ncontract JumpRateModelV2 is BaseJumpRateModelV2 {\n constructor(\n uint256 baseRatePerYear,\n uint256 multiplierPerYear,\n uint256 jumpMultiplierPerYear,\n uint256 kink_,\n IAccessControlManagerV8 accessControlManager_\n )\n BaseJumpRateModelV2(baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_, accessControlManager_)\n /* solhint-disable-next-line no-empty-blocks */\n {\n\n }\n\n /**\n * @notice Calculates the current borrow 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 badDebt The amount of badDebt in the market\n * @return The borrow rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getBorrowRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) external view override returns (uint256) {\n return _getBorrowRate(cash, borrows, reserves, badDebt);\n }\n}\n" + }, + "contracts/Lens/PoolLens.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { RewardsDistributor } from \"../Rewards/RewardsDistributor.sol\";\n\n/**\n * @title PoolLens\n * @author Venus\n * @notice The `PoolLens` contract is designed to retrieve important information for each registered pool. A list of essential information\n * for all pools within the lending protocol can be acquired through the function `getAllPools()`. Additionally, the following records can be\n * looked up for specific pools and markets:\n- the vToken balance of a given user;\n- the pool data (oracle address, associated vToken, liquidation incentive, etc) of a pool via its associated comptroller address;\n- the vToken address in a pool for a given asset;\n- a list of all pools that support an asset;\n- the underlying asset price of a vToken;\n- the metadata (exchange/borrow/supply rate, total supply, collateral factor, etc) of any vToken.\n */\ncontract PoolLens is ExponentialNoError {\n /**\n * @dev Struct for PoolDetails.\n */\n struct PoolData {\n string name;\n address creator;\n address comptroller;\n uint256 blockPosted;\n uint256 timestampPosted;\n string category;\n string logoURL;\n string description;\n address priceOracle;\n uint256 closeFactor;\n uint256 liquidationIncentive;\n uint256 minLiquidatableCollateral;\n VTokenMetadata[] vTokens;\n }\n\n /**\n * @dev Struct for VToken.\n */\n struct VTokenMetadata {\n address vToken;\n uint256 exchangeRateCurrent;\n uint256 supplyRatePerBlock;\n uint256 borrowRatePerBlock;\n uint256 reserveFactorMantissa;\n uint256 supplyCaps;\n uint256 borrowCaps;\n uint256 totalBorrows;\n uint256 totalReserves;\n uint256 totalSupply;\n uint256 totalCash;\n bool isListed;\n uint256 collateralFactorMantissa;\n address underlyingAssetAddress;\n uint256 vTokenDecimals;\n uint256 underlyingDecimals;\n }\n\n /**\n * @dev Struct for VTokenBalance.\n */\n struct VTokenBalances {\n address vToken;\n uint256 balanceOf;\n uint256 borrowBalanceCurrent;\n uint256 balanceOfUnderlying;\n uint256 tokenBalance;\n uint256 tokenAllowance;\n }\n\n /**\n * @dev Struct for underlyingPrice of VToken.\n */\n struct VTokenUnderlyingPrice {\n address vToken;\n uint256 underlyingPrice;\n }\n\n /**\n * @dev Struct with pending reward info for a market.\n */\n struct PendingReward {\n address vTokenAddress;\n uint256 amount;\n }\n\n /**\n * @dev Struct with reward distribution totals for a single reward token and distributor.\n */\n struct RewardSummary {\n address distributorAddress;\n address rewardTokenAddress;\n uint256 totalRewards;\n PendingReward[] pendingRewards;\n }\n\n /**\n * @dev Struct used in RewardDistributor to save last updated market state.\n */\n struct RewardTokenState {\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\n uint224 index;\n // The block number the index was last updated at\n uint32 block;\n // The block number at which to stop rewards\n uint32 lastRewardingBlock;\n }\n\n /**\n * @dev Struct with bad debt of a market denominated\n */\n struct BadDebt {\n address vTokenAddress;\n uint256 badDebtUsd;\n }\n\n /**\n * @dev Struct with bad debt total denominated in usd for a pool and an array of BadDebt structs for each market\n */\n struct BadDebtSummary {\n address comptroller;\n uint256 totalBadDebtUsd;\n BadDebt[] badDebts;\n }\n\n /**\n * @notice Queries the user's supply/borrow balances in vTokens\n * @param vTokens The list of vToken addresses\n * @param account The user Account\n * @return A list of structs containing balances data\n */\n function vTokenBalancesAll(VToken[] calldata vTokens, address account) external returns (VTokenBalances[] memory) {\n uint256 vTokenCount = vTokens.length;\n VTokenBalances[] memory res = new VTokenBalances[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenBalances(vTokens[i], account);\n }\n return res;\n }\n\n /**\n * @notice Queries all pools with addtional details for each of them\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @return Arrays of all Venus pools' data\n */\n function getAllPools(address poolRegistryAddress) external view returns (PoolData[] memory) {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n PoolRegistry.VenusPool[] memory venusPools = poolRegistryInterface.getAllPools();\n uint256 poolLength = venusPools.length;\n\n PoolData[] memory poolDataItems = new PoolData[](poolLength);\n\n for (uint256 i; i < poolLength; ++i) {\n PoolRegistry.VenusPool memory venusPool = venusPools[i];\n PoolData memory poolData = getPoolDataFromVenusPool(poolRegistryAddress, venusPool);\n poolDataItems[i] = poolData;\n }\n\n return poolDataItems;\n }\n\n /**\n * @notice Queries the details of a pool identified by Comptroller address\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param comptroller The Comptroller implementation address\n * @return PoolData structure containing the details of the pool\n */\n function getPoolByComptroller(address poolRegistryAddress, address comptroller)\n external\n view\n returns (PoolData memory)\n {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return getPoolDataFromVenusPool(poolRegistryAddress, poolRegistryInterface.getPoolByComptroller(comptroller));\n }\n\n /**\n * @notice Returns vToken holding the specified underlying asset in the specified pool\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param comptroller The pool comptroller\n * @param asset The underlyingAsset of VToken\n * @return Address of the vToken\n */\n function getVTokenForAsset(\n address poolRegistryAddress,\n address comptroller,\n address asset\n ) external view returns (address) {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return poolRegistryInterface.getVTokenForAsset(comptroller, asset);\n }\n\n /**\n * @notice Returns all pools that support the specified underlying asset\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param asset The underlying asset of vToken\n * @return A list of Comptroller contracts\n */\n function getPoolsSupportedByAsset(address poolRegistryAddress, address asset)\n external\n view\n returns (address[] memory)\n {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return poolRegistryInterface.getPoolsSupportedByAsset(asset);\n }\n\n /**\n * @notice Returns the price data for the underlying assets of the specified vTokens\n * @param vTokens The list of vToken addresses\n * @return An array containing the price data for each asset\n */\n function vTokenUnderlyingPriceAll(VToken[] calldata vTokens)\n external\n view\n returns (VTokenUnderlyingPrice[] memory)\n {\n uint256 vTokenCount = vTokens.length;\n VTokenUnderlyingPrice[] memory res = new VTokenUnderlyingPrice[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenUnderlyingPrice(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Returns the pending rewards for a user for a given pool.\n * @param account The user account.\n * @param comptrollerAddress address\n * @return Pending rewards array\n */\n function getPendingRewards(address account, address comptrollerAddress)\n external\n view\n returns (RewardSummary[] memory)\n {\n VToken[] memory markets = ComptrollerInterface(comptrollerAddress).getAllMarkets();\n RewardsDistributor[] memory rewardsDistributors = ComptrollerViewInterface(comptrollerAddress)\n .getRewardDistributors();\n RewardSummary[] memory rewardSummary = new RewardSummary[](rewardsDistributors.length);\n for (uint256 i; i < rewardsDistributors.length; ++i) {\n RewardSummary memory reward;\n reward.distributorAddress = address(rewardsDistributors[i]);\n reward.rewardTokenAddress = address(rewardsDistributors[i].rewardToken());\n reward.totalRewards = rewardsDistributors[i].rewardTokenAccrued(account);\n reward.pendingRewards = _calculateNotDistributedAwards(account, markets, rewardsDistributors[i]);\n rewardSummary[i] = reward;\n }\n return rewardSummary;\n }\n\n /**\n * @notice Returns a summary of a pool's bad debt broken down by market\n *\n * @param comptrollerAddress Address of the comptroller\n *\n * @return badDebtSummary A struct with comptroller address, total bad debut denominated in usd, and\n * a break down of bad debt by market\n */\n function getPoolBadDebt(address comptrollerAddress) external view returns (BadDebtSummary memory) {\n uint256 totalBadDebtUsd;\n\n // Get every market in the pool\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);\n VToken[] memory markets = comptroller.getAllMarkets();\n ResilientOracleInterface priceOracle = comptroller.oracle();\n\n BadDebt[] memory badDebts = new BadDebt[](markets.length);\n\n BadDebtSummary memory badDebtSummary;\n badDebtSummary.comptroller = comptrollerAddress;\n badDebtSummary.badDebts = badDebts;\n\n // // Calculate the bad debt is USD per market\n for (uint256 i; i < markets.length; ++i) {\n BadDebt memory badDebt;\n badDebt.vTokenAddress = address(markets[i]);\n badDebt.badDebtUsd =\n (VToken(address(markets[i])).badDebt() * priceOracle.getUnderlyingPrice(address(markets[i]))) /\n EXP_SCALE;\n badDebtSummary.badDebts[i] = badDebt;\n totalBadDebtUsd = totalBadDebtUsd + badDebt.badDebtUsd;\n }\n\n badDebtSummary.totalBadDebtUsd = totalBadDebtUsd;\n\n return badDebtSummary;\n }\n\n /**\n * @notice Queries the user's supply/borrow balances in the specified vToken\n * @param vToken vToken address\n * @param account The user Account\n * @return A struct containing the balances data\n */\n function vTokenBalances(VToken vToken, address account) public returns (VTokenBalances memory) {\n uint256 balanceOf = vToken.balanceOf(account);\n uint256 borrowBalanceCurrent = vToken.borrowBalanceCurrent(account);\n uint256 balanceOfUnderlying = vToken.balanceOfUnderlying(account);\n uint256 tokenBalance;\n uint256 tokenAllowance;\n\n IERC20 underlying = IERC20(vToken.underlying());\n tokenBalance = underlying.balanceOf(account);\n tokenAllowance = underlying.allowance(account, address(vToken));\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 Queries additional information for the pool\n * @param poolRegistryAddress Address of the PoolRegistry\n * @param venusPool The VenusPool Object from PoolRegistry\n * @return Enriched PoolData\n */\n function getPoolDataFromVenusPool(address poolRegistryAddress, PoolRegistry.VenusPool memory venusPool)\n public\n view\n returns (PoolData memory)\n {\n // Get tokens in the Pool\n ComptrollerInterface comptrollerInstance = ComptrollerInterface(venusPool.comptroller);\n\n VToken[] memory vTokens = comptrollerInstance.getAllMarkets();\n\n VTokenMetadata[] memory vTokenMetadataItems = vTokenMetadataAll(vTokens);\n\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n\n PoolRegistry.VenusPoolMetaData memory venusPoolMetaData = poolRegistryInterface.getVenusPoolMetadata(\n venusPool.comptroller\n );\n\n ComptrollerViewInterface comptrollerViewInstance = ComptrollerViewInterface(venusPool.comptroller);\n\n PoolData memory poolData = PoolData({\n name: venusPool.name,\n creator: venusPool.creator,\n comptroller: venusPool.comptroller,\n blockPosted: venusPool.blockPosted,\n timestampPosted: venusPool.timestampPosted,\n category: venusPoolMetaData.category,\n logoURL: venusPoolMetaData.logoURL,\n description: venusPoolMetaData.description,\n vTokens: vTokenMetadataItems,\n priceOracle: address(comptrollerViewInstance.oracle()),\n closeFactor: comptrollerViewInstance.closeFactorMantissa(),\n liquidationIncentive: comptrollerViewInstance.liquidationIncentiveMantissa(),\n minLiquidatableCollateral: comptrollerViewInstance.minLiquidatableCollateral()\n });\n\n return poolData;\n }\n\n /**\n * @notice Returns the metadata of VToken\n * @param vToken The address of vToken\n * @return VTokenMetadata struct\n */\n function vTokenMetadata(VToken vToken) public view returns (VTokenMetadata memory) {\n uint256 exchangeRateCurrent = vToken.exchangeRateStored();\n address comptrollerAddress = address(vToken.comptroller());\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);\n (bool isListed, uint256 collateralFactorMantissa) = comptroller.markets(address(vToken));\n\n address underlyingAssetAddress = vToken.underlying();\n uint256 underlyingDecimals = IERC20Metadata(underlyingAssetAddress).decimals();\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 supplyCaps: comptroller.supplyCaps(address(vToken)),\n borrowCaps: comptroller.borrowCaps(address(vToken)),\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 });\n }\n\n /**\n * @notice Returns the metadata of all VTokens\n * @param vTokens The list of vToken addresses\n * @return An array of VTokenMetadata structs\n */\n function vTokenMetadataAll(VToken[] memory vTokens) public view returns (VTokenMetadata[] memory) {\n uint256 vTokenCount = vTokens.length;\n VTokenMetadata[] memory res = new VTokenMetadata[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenMetadata(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Returns the price data for the underlying asset of the specified vToken\n * @param vToken vToken address\n * @return The price data for each asset\n */\n function vTokenUnderlyingPrice(VToken vToken) public view returns (VTokenUnderlyingPrice memory) {\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(address(vToken.comptroller()));\n ResilientOracleInterface priceOracle = comptroller.oracle();\n\n return\n VTokenUnderlyingPrice({\n vToken: address(vToken),\n underlyingPrice: priceOracle.getUnderlyingPrice(address(vToken))\n });\n }\n\n function _calculateNotDistributedAwards(\n address account,\n VToken[] memory markets,\n RewardsDistributor rewardsDistributor\n ) internal view returns (PendingReward[] memory) {\n PendingReward[] memory pendingRewards = new PendingReward[](markets.length);\n for (uint256 i; i < markets.length; ++i) {\n // Market borrow and supply state we will modify update in-memory, in order to not modify storage\n RewardTokenState memory borrowState;\n (borrowState.index, borrowState.block, borrowState.lastRewardingBlock) = rewardsDistributor\n .rewardTokenBorrowState(address(markets[i]));\n RewardTokenState memory supplyState;\n (supplyState.index, supplyState.block, supplyState.lastRewardingBlock) = rewardsDistributor\n .rewardTokenSupplyState(address(markets[i]));\n Exp memory marketBorrowIndex = Exp({ mantissa: markets[i].borrowIndex() });\n\n // Update market supply and borrow index in-memory\n updateMarketBorrowIndex(address(markets[i]), rewardsDistributor, borrowState, marketBorrowIndex);\n updateMarketSupplyIndex(address(markets[i]), rewardsDistributor, supplyState);\n\n // Calculate pending rewards\n uint256 borrowReward = calculateBorrowerReward(\n address(markets[i]),\n rewardsDistributor,\n account,\n borrowState,\n marketBorrowIndex\n );\n uint256 supplyReward = calculateSupplierReward(\n address(markets[i]),\n rewardsDistributor,\n account,\n supplyState\n );\n\n PendingReward memory pendingReward;\n pendingReward.vTokenAddress = address(markets[i]);\n pendingReward.amount = borrowReward + supplyReward;\n pendingRewards[i] = pendingReward;\n }\n return pendingRewards;\n }\n\n function updateMarketBorrowIndex(\n address vToken,\n RewardsDistributor rewardsDistributor,\n RewardTokenState memory borrowState,\n Exp memory marketBorrowIndex\n ) internal view {\n uint256 borrowSpeed = rewardsDistributor.rewardTokenBorrowSpeeds(vToken);\n uint256 blockNumber = block.number;\n\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\n blockNumber = borrowState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(blockNumber, uint256(borrowState.block));\n if (deltaBlocks > 0 && borrowSpeed > 0) {\n // Remove the total earned interest rate since the opening of the market from total borrows\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint256 tokensAccrued = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount > 0 ? fraction(tokensAccrued, 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 function updateMarketSupplyIndex(\n address vToken,\n RewardsDistributor rewardsDistributor,\n RewardTokenState memory supplyState\n ) internal view {\n uint256 supplySpeed = rewardsDistributor.rewardTokenSupplySpeeds(vToken);\n uint256 blockNumber = block.number;\n\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\n blockNumber = supplyState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(blockNumber, uint256(supplyState.block));\n if (deltaBlocks > 0 && supplySpeed > 0) {\n uint256 supplyTokens = VToken(vToken).totalSupply();\n uint256 tokensAccrued = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens > 0 ? fraction(tokensAccrued, 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 function calculateBorrowerReward(\n address vToken,\n RewardsDistributor rewardsDistributor,\n address borrower,\n RewardTokenState memory borrowState,\n Exp memory marketBorrowIndex\n ) internal view returns (uint256) {\n Double memory borrowIndex = Double({ mantissa: borrowState.index });\n Double memory borrowerIndex = Double({\n mantissa: rewardsDistributor.rewardTokenBorrowerIndex(vToken, borrower)\n });\n if (borrowerIndex.mantissa == 0 && borrowIndex.mantissa >= rewardsDistributor.INITIAL_INDEX()) {\n // Covers the case where users borrowed tokens before the market's borrow state index was set\n borrowerIndex.mantissa = rewardsDistributor.INITIAL_INDEX();\n }\n Double memory deltaIndex = sub_(borrowIndex, borrowerIndex);\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\n return borrowerDelta;\n }\n\n function calculateSupplierReward(\n address vToken,\n RewardsDistributor rewardsDistributor,\n address supplier,\n RewardTokenState memory supplyState\n ) internal view returns (uint256) {\n Double memory supplyIndex = Double({ mantissa: supplyState.index });\n Double memory supplierIndex = Double({\n mantissa: rewardsDistributor.rewardTokenSupplierIndex(vToken, supplier)\n });\n if (supplierIndex.mantissa == 0 && supplyIndex.mantissa >= rewardsDistributor.INITIAL_INDEX()) {\n // Covers the case where users supplied tokens before the market's supply state index was set\n supplierIndex.mantissa = rewardsDistributor.INITIAL_INDEX();\n }\n Double memory deltaIndex = sub_(supplyIndex, supplierIndex);\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\n return supplierDelta;\n }\n}\n" + }, + "contracts/lib/constants.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\n\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\nuint256 constant EXP_SCALE = 1e18;\n\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\nuint256 constant MANTISSA_ONE = EXP_SCALE;\n" + }, + "contracts/lib/imports.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n// This file is needed to make hardhat and typechain generate artifacts for\n// contracts we depend on (e.g. in tests or deployments) but not use directly.\n// Another way to do this would be to use hardhat-dependency-compiler, but\n// since we only have a couple of dependencies, installing a separate package\n// seems an overhead.\n\nimport { UpgradeableBeacon } from \"@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol\";\nimport { BeaconProxy } from \"@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol\";\n" + }, + "contracts/lib/TokenDebtTracker.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\n/**\n * @title TokenDebtTracker\n * @author Venus\n * @notice TokenDebtTracker is an abstract contract that handles transfers _out_ of the inheriting contract.\n * If there is an error transferring out (due to any reason, e.g. the token contract restricted the user from\n * receiving incoming transfers), the amount is recorded as a debt that can be claimed later.\n * @dev Note that the inheriting contract keeps some amount of users' tokens on its balance, so be careful when\n * using balanceOf(address(this))!\n */\nabstract contract TokenDebtTracker is Initializable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /**\n * @notice Mapping (IERC20Upgradeable token => (address user => uint256 amount)).\n * Tracks failed transfers: when a token transfer fails, we record the\n * amount of the transfer, so that the user can redeem this debt later.\n */\n mapping(IERC20Upgradeable => mapping(address => uint256)) public tokenDebt;\n\n /**\n * @notice Mapping (IERC20Upgradeable token => uint256 amount) shows how many\n * tokens the contract owes to all users. This is useful for accounting to\n * understand how much of balanceOf(address(this)) is already owed to users.\n */\n mapping(IERC20Upgradeable => uint256) public totalTokenDebt;\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 * @notice Emitted when the contract's debt to the user is increased due to a failed transfer\n * @param token Token address\n * @param user User address\n * @param amount The amount of debt added\n */\n event TokenDebtAdded(address indexed token, address indexed user, uint256 amount);\n\n /**\n * @notice Emitted when a user claims tokens that the contract owes them\n * @param token Token address\n * @param user User address\n * @param amount The amount transferred\n */\n event TokenDebtClaimed(address indexed token, address indexed user, uint256 amount);\n\n /**\n * @notice Thrown if the user tries to claim more tokens than they are owed\n * @param token The token the user is trying to claim\n * @param owedAmount The amount of tokens the contract owes to the user\n * @param amount The amount of tokens the user is trying to claim\n */\n error InsufficientDebt(address token, address user, uint256 owedAmount, uint256 amount);\n\n /**\n * @notice Thrown if trying to transfer more tokens than the contract currently has\n * @param token The token the contract is trying to transfer\n * @param recipient The recipient of the transfer\n * @param amount The amount of tokens the contract is trying to transfer\n * @param availableBalance The amount of tokens the contract currently has\n */\n error InsufficientBalance(address token, address recipient, uint256 amount, uint256 availableBalance);\n\n /**\n * @notice Transfers the tokens we owe to msg.sender, if any\n * @param token The token to claim\n * @param amount_ The amount of tokens to claim (or max uint256 to claim all)\n * @custom:error InsufficientDebt The contract doesn't have enough debt to the user\n */\n function claimTokenDebt(IERC20Upgradeable token, uint256 amount_) external {\n uint256 owedAmount = tokenDebt[token][msg.sender];\n uint256 amount = (amount_ == type(uint256).max ? owedAmount : amount_);\n if (amount > owedAmount) {\n revert InsufficientDebt(address(token), msg.sender, owedAmount, amount);\n }\n unchecked {\n // Safe because we revert if amount > owedAmount above\n tokenDebt[token][msg.sender] = owedAmount - amount;\n }\n totalTokenDebt[token] -= amount;\n emit TokenDebtClaimed(address(token), msg.sender, amount);\n token.safeTransfer(msg.sender, amount);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __TokenDebtTracker_init() internal onlyInitializing {\n __TokenDebtTracker_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __TokenDebtTracker_init_unchained() internal onlyInitializing {}\n\n /**\n * @dev Transfers tokens to the recipient if the contract has enough balance, or\n * records the debt if the transfer fails due to reasons unrelated to the contract's\n * balance (e.g. if the token forbids transfers to the recipient).\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n * @custom:error InsufficientBalance The contract doesn't have enough balance to transfer\n */\n function _transferOutOrTrackDebt(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) internal {\n uint256 balance = token.balanceOf(address(this));\n if (balance < amount) {\n revert InsufficientBalance(address(token), address(this), amount, balance);\n }\n _transferOutOrTrackDebtSkippingBalanceCheck(token, to, amount);\n }\n\n /**\n * @dev Transfers tokens to the recipient, or records the debt if the transfer fails\n * due to any reason, including insufficient balance.\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n */\n function _transferOutOrTrackDebtSkippingBalanceCheck(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) internal {\n // We can't use safeTransfer here because we can't try-catch internal calls\n bool success = _tryTransferOut(token, to, amount);\n if (!success) {\n tokenDebt[token][to] += amount;\n totalTokenDebt[token] += amount;\n emit TokenDebtAdded(address(token), to, amount);\n }\n }\n\n /**\n * @dev Either transfers tokens to the recepient or returns false. Supports tokens\n * thet revert or return false to indicate failure, and the non-compliant ones\n * that do not return any value.\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n * @return true if the transfer succeeded, false otherwise\n */\n function _tryTransferOut(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) private returns (bool) {\n bytes memory callData = abi.encodeCall(token.transfer, (to, amount));\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(callData);\n return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\n }\n}\n" + }, + "contracts/lib/validators.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\nerror ZeroAddressNotAllowed();\n\n/// @notice Checks if the provided address is nonzero, reverts otherwise\n/// @param address_ Address to check\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\nfunction ensureNonzeroAddress(address address_) pure {\n if (address_ == address(0)) {\n revert ZeroAddressNotAllowed();\n }\n}\n" + }, + "contracts/MaxLoopsLimitHelper.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title MaxLoopsLimitHelper\n * @author Venus\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\n */\nabstract contract MaxLoopsLimitHelper {\n // Limit for the loops to avoid the DOS\n uint256 public maxLoopsLimit;\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 max loops limit is set\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\n\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function _setMaxLoopsLimit(uint256 limit) internal {\n require(limit > maxLoopsLimit, \"Comptroller: Invalid maxLoopsLimit\");\n\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\n maxLoopsLimit = limit;\n\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\n }\n\n /**\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\n * @param len Length of the loops iterate\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\n */\n function _ensureMaxLoops(uint256 len) internal view {\n if (len > maxLoopsLimit) {\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\n }\n }\n}\n" + }, + "contracts/Pool/PoolRegistry.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { PoolRegistryInterface } from \"./PoolRegistryInterface.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\n\n/**\n * @title PoolRegistry\n * @author Venus\n * @notice The Isolated Pools architecture centers around the `PoolRegistry` contract. The `PoolRegistry` maintains a directory of isolated lending\n * pools and can perform actions like creating and registering new pools, adding new markets to existing pools, setting and updating the pool's required\n * metadata, and providing the getter methods to get information on the pools.\n *\n * Isolated lending has three main components: PoolRegistry, pools, and markets. The PoolRegistry is responsible for managing pools.\n * It can create new pools, update pool metadata and manage markets within pools. PoolRegistry contains getter methods to get the details of\n * any existing pool like `getVTokenForAsset` and `getPoolsSupportedByAsset`. It also contains methods for updating pool metadata (`updatePoolMetadata`)\n * and setting pool name (`setPoolName`).\n *\n * The directory of pools is managed through two mappings: `_poolByComptroller` which is a hashmap with the comptroller address as the key and `VenusPool` as\n * the value and `_poolsByID` which is an array of comptroller addresses. Individual pools can be accessed by calling `getPoolByComptroller` with the pool's\n * comptroller address. `_poolsByID` is used to iterate through all of the pools.\n *\n * PoolRegistry also contains a map of asset addresses called `_supportedPools` that maps to an array of assets suppored by each pool. This array of pools by\n * asset is retrieved by calling `getPoolsSupportedByAsset`.\n *\n * PoolRegistry registers new isolated pools in the directory with the `createRegistryPool` method. Isolated pools are composed of independent markets with\n * specific assets and custom risk management configurations according to their markets.\n */\ncontract PoolRegistry is Ownable2StepUpgradeable, AccessControlledV8, PoolRegistryInterface {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n struct AddMarketInput {\n VToken vToken;\n uint256 collateralFactor;\n uint256 liquidationThreshold;\n uint256 initialSupply;\n address vTokenReceiver;\n uint256 supplyCap;\n uint256 borrowCap;\n }\n\n uint256 internal constant MAX_POOL_NAME_LENGTH = 100;\n\n /**\n * @notice Maps pool's comptroller address to metadata.\n */\n mapping(address => VenusPoolMetaData) public metadata;\n\n /**\n * @dev Maps pool ID to pool's comptroller address\n */\n mapping(uint256 => address) private _poolsByID;\n\n /**\n * @dev Total number of pools created.\n */\n uint256 private _numberOfPools;\n\n /**\n * @dev Maps comptroller address to Venus pool Index.\n */\n mapping(address => VenusPool) private _poolByComptroller;\n\n /**\n * @dev Maps pool's comptroller address to asset to vToken.\n */\n mapping(address => mapping(address => address)) private _vTokens;\n\n /**\n * @dev Maps asset to list of supported pools.\n */\n mapping(address => address[]) private _supportedPools;\n\n /**\n * @notice Emitted when a new Venus pool is added to the directory.\n */\n event PoolRegistered(address indexed comptroller, VenusPool pool);\n\n /**\n * @notice Emitted when a pool name is set.\n */\n event PoolNameSet(address indexed comptroller, string oldName, string newName);\n\n /**\n * @notice Emitted when a pool metadata is updated.\n */\n event PoolMetadataUpdated(\n address indexed comptroller,\n VenusPoolMetaData oldMetadata,\n VenusPoolMetaData newMetadata\n );\n\n /**\n * @notice Emitted when a Market is added to the pool.\n */\n event MarketAdded(address indexed comptroller, address indexed vTokenAddress);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner\n * @param accessControlManager_ AccessControlManager contract address\n */\n function initialize(address accessControlManager_) external initializer {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n }\n\n /**\n * @notice Adds a new Venus pool to the directory\n * @dev Price oracle must be configured before adding a pool\n * @param name The name of the pool\n * @param comptroller Pool's Comptroller contract\n * @param closeFactor The pool's close factor (scaled by 1e18)\n * @param liquidationIncentive The pool's liquidation incentive (scaled by 1e18)\n * @param minLiquidatableCollateral Minimal collateral for regular (non-batch) liquidations flow\n * @return index The index of the registered Venus pool\n * @custom:error ZeroAddressNotAllowed is thrown when Comptroller address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when price oracle address is zero\n */\n function addPool(\n string calldata name,\n Comptroller comptroller,\n uint256 closeFactor,\n uint256 liquidationIncentive,\n uint256 minLiquidatableCollateral\n ) external virtual returns (uint256 index) {\n _checkAccessAllowed(\"addPool(string,address,uint256,uint256,uint256)\");\n // Input validation\n ensureNonzeroAddress(address(comptroller));\n ensureNonzeroAddress(address(comptroller.oracle()));\n\n uint256 poolId = _registerPool(name, address(comptroller));\n\n // Set Venus pool parameters\n comptroller.setCloseFactor(closeFactor);\n comptroller.setLiquidationIncentive(liquidationIncentive);\n comptroller.setMinLiquidatableCollateral(minLiquidatableCollateral);\n\n return poolId;\n }\n\n /**\n * @notice Add a market to an existing pool and then mint to provide initial supply\n * @param input The structure describing the parameters for adding a market to a pool\n * @custom:error ZeroAddressNotAllowed is thrown when vToken address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when vTokenReceiver address is zero\n */\n function addMarket(AddMarketInput memory input) external {\n _checkAccessAllowed(\"addMarket(AddMarketInput)\");\n ensureNonzeroAddress(address(input.vToken));\n ensureNonzeroAddress(input.vTokenReceiver);\n require(input.initialSupply > 0, \"PoolRegistry: initialSupply is zero\");\n\n VToken vToken = input.vToken;\n address vTokenAddress = address(vToken);\n address comptrollerAddress = address(vToken.comptroller());\n Comptroller comptroller = Comptroller(comptrollerAddress);\n address underlyingAddress = vToken.underlying();\n IERC20Upgradeable underlying = IERC20Upgradeable(underlyingAddress);\n\n require(_poolByComptroller[comptrollerAddress].creator != address(0), \"PoolRegistry: Pool not registered\");\n // solhint-disable-next-line reason-string\n require(\n _vTokens[comptrollerAddress][underlyingAddress] == address(0),\n \"PoolRegistry: Market already added for asset comptroller combination\"\n );\n\n comptroller.supportMarket(vToken);\n comptroller.setCollateralFactor(vToken, input.collateralFactor, input.liquidationThreshold);\n\n uint256[] memory newSupplyCaps = new uint256[](1);\n uint256[] memory newBorrowCaps = new uint256[](1);\n VToken[] memory vTokens = new VToken[](1);\n\n newSupplyCaps[0] = input.supplyCap;\n newBorrowCaps[0] = input.borrowCap;\n vTokens[0] = vToken;\n\n comptroller.setMarketSupplyCaps(vTokens, newSupplyCaps);\n comptroller.setMarketBorrowCaps(vTokens, newBorrowCaps);\n\n _vTokens[comptrollerAddress][underlyingAddress] = vTokenAddress;\n _supportedPools[underlyingAddress].push(comptrollerAddress);\n\n uint256 amountToSupply = _transferIn(underlying, msg.sender, input.initialSupply);\n underlying.approve(vTokenAddress, 0);\n underlying.approve(vTokenAddress, amountToSupply);\n vToken.mintBehalf(input.vTokenReceiver, amountToSupply);\n\n emit MarketAdded(comptrollerAddress, vTokenAddress);\n }\n\n /**\n * @notice Modify existing Venus pool name\n * @param comptroller Pool's Comptroller\n * @param name New pool name\n */\n function setPoolName(address comptroller, string calldata name) external {\n _checkAccessAllowed(\"setPoolName(address,string)\");\n _ensureValidName(name);\n VenusPool storage pool = _poolByComptroller[comptroller];\n string memory oldName = pool.name;\n pool.name = name;\n emit PoolNameSet(comptroller, oldName, name);\n }\n\n /**\n * @notice Update metadata of an existing pool\n * @param comptroller Pool's Comptroller\n * @param metadata_ New pool metadata\n */\n function updatePoolMetadata(address comptroller, VenusPoolMetaData calldata metadata_) external {\n _checkAccessAllowed(\"updatePoolMetadata(address,VenusPoolMetaData)\");\n VenusPoolMetaData memory oldMetadata = metadata[comptroller];\n metadata[comptroller] = metadata_;\n emit PoolMetadataUpdated(comptroller, oldMetadata, metadata_);\n }\n\n /**\n * @notice Returns arrays of all Venus pools' data\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\n * @return A list of all pools within PoolRegistry, with details for each pool\n */\n function getAllPools() external view override returns (VenusPool[] memory) {\n uint256 numberOfPools_ = _numberOfPools; // storage load to save gas\n VenusPool[] memory _pools = new VenusPool[](numberOfPools_);\n for (uint256 i = 1; i <= numberOfPools_; ++i) {\n address comptroller = _poolsByID[i];\n _pools[i - 1] = (_poolByComptroller[comptroller]);\n }\n return _pools;\n }\n\n /**\n * @param comptroller The comptroller proxy address associated to the pool\n * @return Returns Venus pool\n */\n function getPoolByComptroller(address comptroller) external view override returns (VenusPool memory) {\n return _poolByComptroller[comptroller];\n }\n\n /**\n * @param comptroller comptroller of Venus pool\n * @return Returns Metadata of Venus pool\n */\n function getVenusPoolMetadata(address comptroller) external view override returns (VenusPoolMetaData memory) {\n return metadata[comptroller];\n }\n\n function getVTokenForAsset(address comptroller, address asset) external view override returns (address) {\n return _vTokens[comptroller][asset];\n }\n\n function getPoolsSupportedByAsset(address asset) external view override returns (address[] memory) {\n return _supportedPools[asset];\n }\n\n /**\n * @dev Adds a new Venus pool to the directory (without checking msg.sender).\n * @param name The name of the pool\n * @param comptroller The pool's Comptroller proxy contract address\n * @return The index of the registered Venus pool\n */\n function _registerPool(string calldata name, address comptroller) internal returns (uint256) {\n VenusPool storage storedPool = _poolByComptroller[comptroller];\n\n require(storedPool.creator == address(0), \"PoolRegistry: Pool already exists in the directory.\");\n _ensureValidName(name);\n\n ++_numberOfPools;\n uint256 numberOfPools_ = _numberOfPools; // cache on stack to save storage read gas\n\n VenusPool memory pool = VenusPool(name, msg.sender, comptroller, block.number, block.timestamp);\n\n _poolsByID[numberOfPools_] = comptroller;\n _poolByComptroller[comptroller] = pool;\n\n emit PoolRegistered(comptroller, pool);\n return numberOfPools_;\n }\n\n function _transferIn(\n IERC20Upgradeable token,\n address from,\n uint256 amount\n ) internal returns (uint256) {\n uint256 balanceBefore = token.balanceOf(address(this));\n token.safeTransferFrom(from, address(this), amount);\n uint256 balanceAfter = token.balanceOf(address(this));\n return balanceAfter - balanceBefore;\n }\n\n function _ensureValidName(string calldata name) internal pure {\n require(bytes(name).length <= MAX_POOL_NAME_LENGTH, \"Pool's name is too large\");\n }\n}\n" + }, + "contracts/Pool/PoolRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title PoolRegistryInterface\n * @author Venus\n * @notice Interface implemented by `PoolRegistry`.\n */\ninterface PoolRegistryInterface {\n /**\n * @notice Struct for a Venus interest rate pool.\n */\n struct VenusPool {\n string name;\n address creator;\n address comptroller;\n uint256 blockPosted;\n uint256 timestampPosted;\n }\n\n /**\n * @notice Struct for a Venus interest rate pool metadata.\n */\n struct VenusPoolMetaData {\n string category;\n string logoURL;\n string description;\n }\n\n /// @notice Get all pools in PoolRegistry\n function getAllPools() external view returns (VenusPool[] memory);\n\n /// @notice Get a pool by comptroller address\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\n\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\n\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\n\n /// @notice Get the metadata of a Pool by comptroller address\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\n}\n" + }, + "contracts/Rewards/RewardsDistributor.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { MaxLoopsLimitHelper } from \"../MaxLoopsLimitHelper.sol\";\n\n/**\n * @title `RewardsDistributor`\n * @author Venus\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\n * token to be released each block for borrowers and suppliers, which is distributed based on a user’s percentage of the borrows or supplies\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\n *\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\n */\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n struct RewardToken {\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\n uint224 index;\n // The block number the index was last updated at\n uint32 block;\n // The block number at which to stop rewards\n uint32 lastRewardingBlock;\n }\n\n /// @notice The initial REWARD TOKEN index for a market\n uint224 public constant INITIAL_INDEX = 1e36;\n\n /// @notice The REWARD TOKEN market supply state for each market\n mapping(address => RewardToken) public rewardTokenSupplyState;\n\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\n\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\n mapping(address => uint256) public rewardTokenAccrued;\n\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\n\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\n mapping(address => uint256) public rewardTokenSupplySpeeds;\n\n /// @notice The REWARD TOKEN market borrow state for each market\n mapping(address => RewardToken) public rewardTokenBorrowState;\n\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\n mapping(address => uint256) public rewardTokenContributorSpeeds;\n\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\n mapping(address => uint256) public lastContributorBlock;\n\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\n\n Comptroller private comptroller;\n\n IERC20Upgradeable public rewardToken;\n\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\n event DistributedSupplierRewardToken(\n VToken indexed vToken,\n address indexed supplier,\n uint256 rewardTokenDelta,\n uint256 rewardTokenTotal,\n uint256 rewardTokenSupplyIndex\n );\n\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\n event DistributedBorrowerRewardToken(\n VToken indexed vToken,\n address indexed borrower,\n uint256 rewardTokenDelta,\n uint256 rewardTokenTotal,\n uint256 rewardTokenBorrowIndex\n );\n\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /// @notice Emitted when REWARD TOKEN is granted by admin\n event RewardTokenGranted(address indexed recipient, uint256 amount);\n\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\n\n /// @notice Emitted when a market is initialized\n event MarketInitialized(address indexed vToken);\n\n /// @notice Emitted when a reward token supply index is updated\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\n\n /// @notice Emitted when a reward token borrow index is updated\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\n\n /// @notice Emitted when a reward for contributor is updated\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\n\n /// @notice Emitted when a reward token last rewarding block for supply is updated\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\n\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\n\n modifier onlyComptroller() {\n require(address(comptroller) == msg.sender, \"Only comptroller can call this function\");\n _;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice RewardsDistributor initializer\n * @dev Initializes the deployer to owner\n * @param comptroller_ Comptroller to attach the reward distributor to\n * @param rewardToken_ Reward token to distribute\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\n * @param accessControlManager_ AccessControlManager contract address\n */\n function initialize(\n Comptroller comptroller_,\n IERC20Upgradeable rewardToken_,\n uint256 loopsLimit_,\n address accessControlManager_\n ) external initializer {\n comptroller = comptroller_;\n rewardToken = rewardToken_;\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n\n _setMaxLoopsLimit(loopsLimit_);\n }\n\n function initializeMarket(address vToken) external onlyComptroller {\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\n }\n\n if (borrowState.index == 0) {\n // Initialize borrow state index with default value\n borrowState.index = INITIAL_INDEX;\n }\n\n /*\n * Update market state block numbers\n */\n supplyState.block = borrowState.block = blockNumber;\n\n emit MarketInitialized(vToken);\n }\n\n /*** Reward Token Distribution ***/\n\n /**\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\n * Borrowers will begin to accrue after the first interaction with the protocol.\n * @dev This function should only be called when the user has a borrow position in the market\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\n * @param vToken The market in which the borrower is interacting\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\n * @param marketBorrowIndex The current global borrow index of vToken\n */\n function distributeBorrowerRewardToken(\n address vToken,\n address borrower,\n Exp memory marketBorrowIndex\n ) external onlyComptroller {\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\n }\n\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\n _updateRewardTokenSupplyIndex(vToken);\n }\n\n /**\n * @notice Transfer REWARD TOKEN to the recipient\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\n */\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\n uint256 amountLeft = _grantRewardToken(recipient, amount);\n require(amountLeft == 0, \"insufficient rewardToken for grant\");\n emit RewardTokenGranted(recipient, amount);\n }\n\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\n }\n\n /**\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\n * @param vTokens The markets whose REWARD TOKEN speed to update\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\n */\n function setRewardTokenSpeeds(\n VToken[] memory vTokens,\n uint256[] memory supplySpeeds,\n uint256[] memory borrowSpeeds\n ) external {\n _checkAccessAllowed(\"setRewardTokenSpeeds(address[],uint256[],uint256[])\");\n uint256 numTokens = vTokens.length;\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \"invalid setRewardTokenSpeeds\");\n\n for (uint256 i; i < numTokens; ++i) {\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\n }\n }\n\n /**\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\n */\n function setLastRewardingBlocks(\n VToken[] calldata vTokens,\n uint32[] calldata supplyLastRewardingBlocks,\n uint32[] calldata borrowLastRewardingBlocks\n ) external {\n _checkAccessAllowed(\"setLastRewardingBlock(address[],uint32[],uint32[])\");\n uint256 numTokens = vTokens.length;\n require(\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\n \"RewardsDistributor::setLastRewardingBlocks invalid input\"\n );\n\n for (uint256 i; i < numTokens; ) {\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Set REWARD TOKEN speed for a single contributor\n * @param contributor The contributor whose REWARD TOKEN speed to update\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\n */\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\n updateContributorRewards(contributor);\n if (rewardTokenSpeed == 0) {\n // release storage\n delete lastContributorBlock[contributor];\n } else {\n lastContributorBlock[contributor] = getBlockNumber();\n }\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\n\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\n }\n\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\n _distributeSupplierRewardToken(vToken, supplier);\n }\n\n /**\n * @notice Claim all the rewardToken accrued by holder in all markets\n * @param holder The address to claim REWARD TOKEN for\n */\n function claimRewardToken(address holder) external {\n return claimRewardToken(holder, comptroller.getAllMarkets());\n }\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\n * @param contributor The address to calculate contributor rewards for\n */\n function updateContributorRewards(address contributor) public {\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\n uint256 blockNumber = getBlockNumber();\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\n\n rewardTokenAccrued[contributor] = contributorAccrued;\n lastContributorBlock[contributor] = blockNumber;\n\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\n }\n }\n\n /**\n * @notice Claim all the rewardToken accrued by holder in the specified markets\n * @param holder The address to claim REWARD TOKEN for\n * @param vTokens The list of markets to claim REWARD TOKEN in\n */\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\n uint256 vTokensCount = vTokens.length;\n\n _ensureMaxLoops(vTokensCount);\n\n for (uint256 i; i < vTokensCount; ++i) {\n VToken vToken = vTokens[i];\n require(comptroller.isMarketListed(vToken), \"market must be listed\");\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\n _updateRewardTokenSupplyIndex(address(vToken));\n _distributeSupplierRewardToken(address(vToken), holder);\n }\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\n }\n\n function getBlockNumber() public view virtual returns (uint256) {\n return block.number;\n }\n\n /**\n * @notice Set REWARD TOKEN last rewarding block for a single market.\n * @param vToken market's whose reward token last rewarding block to be updated\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\n */\n function _setLastRewardingBlock(\n VToken vToken,\n uint32 supplyLastRewardingBlock,\n uint32 borrowLastRewardingBlock\n ) internal {\n require(comptroller.isMarketListed(vToken), \"rewardToken market is not listed\");\n\n uint256 blockNumber = getBlockNumber();\n\n require(supplyLastRewardingBlock > blockNumber, \"setting last rewarding block in the past is not allowed\");\n require(borrowLastRewardingBlock > blockNumber, \"setting last rewarding block in the past is not allowed\");\n\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\n\n require(\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\n \"this RewardsDistributor is already locked\"\n );\n require(\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\n \"this RewardsDistributor is already locked\"\n );\n\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\n }\n\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\n }\n }\n\n /**\n * @notice Set REWARD TOKEN speed for a single market.\n * @param vToken market's whose reward token rate to be updated\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\n */\n function _setRewardTokenSpeed(\n VToken vToken,\n uint256 supplySpeed,\n uint256 borrowSpeed\n ) internal {\n require(comptroller.isMarketListed(vToken), \"rewardToken market is not listed\");\n\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\n // Supply speed updated so let's update supply state to ensure that\n // 1. REWARD TOKEN accrued properly for the old speed, and\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\n _updateRewardTokenSupplyIndex(address(vToken));\n\n // Update speed and emit event\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\n }\n\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\n // Borrow speed updated so let's update borrow state to ensure that\n // 1. REWARD TOKEN accrued properly for the old speed, and\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\n\n // Update speed and emit event\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\n }\n }\n\n /**\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\n */\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n uint256 supplyIndex = supplyState.index;\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\n\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\n\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\n // Covers the case where users supplied tokens before the market's supply state index was set.\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\n // set for the market.\n supplierIndex = INITIAL_INDEX;\n }\n\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\n\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\n\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\n\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\n rewardTokenAccrued[supplier] = supplierAccrued;\n\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\n }\n\n /**\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\n * @param vToken The market in which the borrower is interacting\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\n * @param marketBorrowIndex The current global borrow index of vToken\n */\n function _distributeBorrowerRewardToken(\n address vToken,\n address borrower,\n Exp memory marketBorrowIndex\n ) internal {\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\n uint256 borrowIndex = borrowState.index;\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\n\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\n\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\n // set for the market.\n borrowerIndex = INITIAL_INDEX;\n }\n\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\n\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\n\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\n if (borrowerAmount != 0) {\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\n\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\n rewardTokenAccrued[borrower] = borrowerAccrued;\n\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\n }\n }\n\n /**\n * @notice Transfer REWARD TOKEN to the user.\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\n * @param user The address of the user to transfer REWARD TOKEN to\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\n */\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\n if (amount > 0 && amount <= rewardTokenRemaining) {\n rewardToken.safeTransfer(user, amount);\n return 0;\n }\n return amount;\n }\n\n /**\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\n * @param vToken The market whose supply index to update\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\n */\n function _updateRewardTokenSupplyIndex(address vToken) internal {\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\n blockNumber = supplyState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\n\n if (deltaBlocks > 0 && supplySpeed > 0) {\n uint256 supplyTokens = VToken(vToken).totalSupply();\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens > 0\n ? fraction(accruedSinceUpdate, supplyTokens)\n : Double({ mantissa: 0 });\n supplyState.index = safe224(\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\n \"new index exceeds 224 bits\"\n );\n supplyState.block = blockNumber;\n } else if (deltaBlocks > 0) {\n supplyState.block = blockNumber;\n }\n\n emit RewardTokenSupplyIndexUpdated(vToken);\n }\n\n /**\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\n * @param vToken The market whose borrow index to update\n * @param marketBorrowIndex The current global borrow index of vToken\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\n */\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\n blockNumber = borrowState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\n if (deltaBlocks > 0 && borrowSpeed > 0) {\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount > 0\n ? fraction(accruedSinceUpdate, borrowAmount)\n : Double({ mantissa: 0 });\n borrowState.index = safe224(\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\n \"new index exceeds 224 bits\"\n );\n borrowState.block = blockNumber;\n } else if (deltaBlocks > 0) {\n borrowState.block = blockNumber;\n }\n\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\n }\n}\n" + }, + "contracts/RiskFund/IProtocolShareReserve.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title IProtocolShareReserve\n * @author Venus\n * @notice Interface implemented by `ProtocolShareReserve`.\n */\ninterface IProtocolShareReserve {\n function updateAssetsState(address comptroller, address asset) external;\n}\n" + }, + "contracts/RiskFund/IRiskFund.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title IRiskFund\n * @author Venus\n * @notice Interface implemented by `RiskFund`.\n */\ninterface IRiskFund {\n function swapPoolsAssets(\n address[] calldata markets,\n uint256[] calldata amountsOutMin,\n address[][] calldata paths,\n uint256 deadline\n ) external returns (uint256);\n\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\n\n function updateAssetsState(address comptroller, address asset) external;\n\n function convertibleBaseAsset() external view returns (address);\n\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\n}\n" + }, + "contracts/RiskFund/ProtocolShareReserve.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\nimport { IProtocolShareReserve } from \"./IProtocolShareReserve.sol\";\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { ReserveHelpers } from \"./ReserveHelpers.sol\";\nimport { IRiskFund } from \"./IRiskFund.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\n\ncontract ProtocolShareReserve is ExponentialNoError, ReserveHelpers, IProtocolShareReserve {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n address public protocolIncome;\n address public riskFund;\n // Percentage of funds not sent to the RiskFund contract when the funds are released, following the project Tokenomics\n uint256 private constant PROTOCOL_SHARE_PERCENTAGE = 50;\n uint256 private constant BASE_UNIT = 100;\n\n /// @notice Emitted when funds are released\n event FundsReleased(address indexed comptroller, address indexed asset, uint256 amount);\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner.\n * @param protocolIncome_ The address protocol income will be sent to\n * @param riskFund_ Risk fund address\n * @custom:error ZeroAddressNotAllowed is thrown when protocol income address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\n */\n function initialize(address protocolIncome_, address riskFund_) external initializer {\n ensureNonzeroAddress(protocolIncome_);\n ensureNonzeroAddress(riskFund_);\n\n __Ownable2Step_init();\n\n protocolIncome = protocolIncome_;\n riskFund = riskFund_;\n }\n\n /**\n * @notice Pool registry setter.\n * @param poolRegistry_ Address of the pool registry\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Release funds\n * @param comptroller Pool's Comptroller\n * @param asset Asset to be released\n * @param amount Amount to release\n * @return Number of total released tokens\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function releaseFunds(\n address comptroller,\n address asset,\n uint256 amount\n ) external returns (uint256) {\n ensureNonzeroAddress(asset);\n require(amount <= poolsAssetsReserves[comptroller][asset], \"ProtocolShareReserve: Insufficient pool balance\");\n\n assetsReserves[asset] -= amount;\n poolsAssetsReserves[comptroller][asset] -= amount;\n uint256 protocolIncomeAmount = mul_(\n Exp({ mantissa: amount }),\n div_(Exp({ mantissa: PROTOCOL_SHARE_PERCENTAGE * EXP_SCALE }), BASE_UNIT)\n ).mantissa;\n\n address riskFund_ = riskFund;\n\n IERC20Upgradeable(asset).safeTransfer(protocolIncome, protocolIncomeAmount);\n IERC20Upgradeable(asset).safeTransfer(riskFund_, amount - protocolIncomeAmount);\n\n // Update the pool asset's state in the risk fund for the above transfer.\n IRiskFund(riskFund_).updateAssetsState(comptroller, asset);\n\n emit FundsReleased(comptroller, asset, amount);\n\n return amount;\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to the protocol share reserve.\n * @param comptroller Comptroller address(pool)\n * @param asset Asset address.\n */\n function updateAssetsState(address comptroller, address asset)\n public\n override(IProtocolShareReserve, ReserveHelpers)\n {\n super.updateAssetsState(comptroller, asset);\n }\n}\n" + }, + "contracts/RiskFund/ReserveHelpers.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\n\ncontract ReserveHelpers is Ownable2StepUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n uint256 private constant NOT_ENTERED = 1;\n\n uint256 private constant ENTERED = 2;\n\n // Store the previous state for the asset transferred to ProtocolShareReserve combined(for all pools).\n mapping(address => uint256) public assetsReserves;\n\n // Store the asset's reserve per pool in the ProtocolShareReserve.\n // Comptroller(pool) -> Asset -> amount\n mapping(address => mapping(address => uint256)) public poolsAssetsReserves;\n\n // Address of pool registry contract\n address public poolRegistry;\n\n /**\n * @dev Guard variable for re-entrancy checks\n */\n uint256 internal status;\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 */\n uint256[46] private __gap;\n\n /// @notice Event emitted after the update of the assets reserves.\n /// @param comptroller Pool's Comptroller address\n /// @param asset Token address\n /// @param amount An amount by which the reserves have increased\n event AssetsReservesUpdated(address indexed comptroller, address indexed asset, uint256 amount);\n\n /// @notice event emitted on sweep token success\n event SweepToken(address indexed token, address indexed to, uint256 amount);\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(status != ENTERED, \"re-entered\");\n status = ENTERED;\n _;\n status = NOT_ENTERED;\n }\n\n /**\n * @notice A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\n * @param _token The address of the BEP-20 token to sweep\n * @param _to Recipient of the output tokens.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n * @custom:access Only Owner\n */\n function sweepToken(address _token, address _to) external onlyOwner nonReentrant {\n ensureNonzeroAddress(_to);\n uint256 balanceDfference_;\n uint256 balance_ = IERC20Upgradeable(_token).balanceOf(address(this));\n\n require(balance_ > assetsReserves[_token], \"ReserveHelpers: Zero surplus tokens\");\n unchecked {\n balanceDfference_ = balance_ - assetsReserves[_token];\n }\n\n IERC20Upgradeable(_token).safeTransfer(_to, balanceDfference_);\n emit SweepToken(_token, _to, balanceDfference_);\n }\n\n /**\n * @notice Get the Amount of the asset in the risk fund for the specific pool.\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n * @return Asset's reserve in risk fund.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function getPoolAssetReserve(address comptroller, address asset) external view returns (uint256) {\n ensureNonzeroAddress(asset);\n require(ComptrollerInterface(comptroller).isComptroller(), \"ReserveHelpers: Comptroller address invalid\");\n return poolsAssetsReserves[comptroller][asset];\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund\n * and transferring funds to the protocol share reserve\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function updateAssetsState(address comptroller, address asset) public virtual {\n ensureNonzeroAddress(asset);\n require(ComptrollerInterface(comptroller).isComptroller(), \"ReserveHelpers: Comptroller address invalid\");\n address poolRegistry_ = poolRegistry;\n require(poolRegistry_ != address(0), \"ReserveHelpers: Pool Registry address is not set\");\n require(\n PoolRegistryInterface(poolRegistry_).getVTokenForAsset(comptroller, asset) != address(0),\n \"ReserveHelpers: The pool doesn't support the asset\"\n );\n\n uint256 currentBalance = IERC20Upgradeable(asset).balanceOf(address(this));\n uint256 assetReserve = assetsReserves[asset];\n if (currentBalance > assetReserve) {\n uint256 balanceDifference;\n unchecked {\n balanceDifference = currentBalance - assetReserve;\n }\n assetsReserves[asset] += balanceDifference;\n poolsAssetsReserves[comptroller][asset] += balanceDifference;\n emit AssetsReservesUpdated(comptroller, asset, balanceDifference);\n }\n }\n}\n" + }, + "contracts/RiskFund/RiskFund.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { IRiskFund } from \"./IRiskFund.sol\";\nimport { ReserveHelpers } from \"./ReserveHelpers.sol\";\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { IPancakeswapV2Router } from \"../IPancakeswapV2Router.sol\";\nimport { IShortfall } from \"../Shortfall/IShortfall.sol\";\nimport { MaxLoopsLimitHelper } from \"../MaxLoopsLimitHelper.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\n\n/**\n * @title ReserveHelpers\n * @author Venus\n * @notice Contract with basic features to track/hold different assets for different Comptrollers.\n * @dev This contract does not support BNB.\n */\ncontract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, MaxLoopsLimitHelper, IRiskFund {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n address public convertibleBaseAsset;\n address public shortfall;\n address public pancakeSwapRouter;\n uint256 public minAmountToConvert;\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @notice Emitted when shortfall contract address is updated\n event ShortfallContractUpdated(address indexed oldShortfallContract, address indexed newShortfallContract);\n\n /// @notice Emitted when PancakeSwap router contract address is updated\n event PancakeSwapRouterUpdated(address indexed oldPancakeSwapRouter, address indexed newPancakeSwapRouter);\n\n /// @notice Emitted when minimum amount to convert is updated\n event MinAmountToConvertUpdated(uint256 oldMinAmountToConvert, uint256 newMinAmountToConvert);\n\n /// @notice Emitted when pools assets are swapped\n event SwappedPoolsAssets(address[] markets, uint256[] amountsOutMin, uint256 totalAmount);\n\n /// @notice Emitted when reserves are transferred for auction\n event TransferredReserveForAuction(address indexed comptroller, uint256 amount);\n\n /// @dev Note that the contract is upgradeable. Use initialize() or reinitializers\n /// to set the state variables.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner.\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\n * @param minAmountToConvert_ Minimum amount assets must be worth to convert into base asset\n * @param convertibleBaseAsset_ Address of the base asset\n * @param accessControlManager_ Address of the access control contract\n * @param loopsLimit_ Limit for the loops in the contract to avoid DOS\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\n */\n function initialize(\n address pancakeSwapRouter_,\n uint256 minAmountToConvert_,\n address convertibleBaseAsset_,\n address accessControlManager_,\n uint256 loopsLimit_\n ) external initializer {\n ensureNonzeroAddress(pancakeSwapRouter_);\n ensureNonzeroAddress(convertibleBaseAsset_);\n require(minAmountToConvert_ > 0, \"Risk Fund: Invalid min amount to convert\");\n require(loopsLimit_ > 0, \"Risk Fund: Loops limit can not be zero\");\n\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n\n pancakeSwapRouter = pancakeSwapRouter_;\n minAmountToConvert = minAmountToConvert_;\n convertibleBaseAsset = convertibleBaseAsset_;\n\n _setMaxLoopsLimit(loopsLimit_);\n }\n\n /**\n * @notice Pool registry setter\n * @param poolRegistry_ Address of the pool registry\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Shortfall contract address setter\n * @param shortfallContractAddress_ Address of the auction contract\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n */\n function setShortfallContractAddress(address shortfallContractAddress_) external onlyOwner {\n ensureNonzeroAddress(shortfallContractAddress_);\n require(\n IShortfall(shortfallContractAddress_).convertibleBaseAsset() == convertibleBaseAsset,\n \"Risk Fund: Base asset doesn't match\"\n );\n\n address oldShortfallContractAddress = shortfall;\n shortfall = shortfallContractAddress_;\n emit ShortfallContractUpdated(oldShortfallContractAddress, shortfallContractAddress_);\n }\n\n /**\n * @notice PancakeSwap router address setter\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\n */\n function setPancakeSwapRouter(address pancakeSwapRouter_) external onlyOwner {\n ensureNonzeroAddress(pancakeSwapRouter_);\n address oldPancakeSwapRouter = pancakeSwapRouter;\n pancakeSwapRouter = pancakeSwapRouter_;\n emit PancakeSwapRouterUpdated(oldPancakeSwapRouter, pancakeSwapRouter_);\n }\n\n /**\n * @notice Min amount to convert setter\n * @param minAmountToConvert_ Min amount to convert.\n */\n function setMinAmountToConvert(uint256 minAmountToConvert_) external {\n _checkAccessAllowed(\"setMinAmountToConvert(uint256)\");\n require(minAmountToConvert_ > 0, \"Risk Fund: Invalid min amount to convert\");\n uint256 oldMinAmountToConvert = minAmountToConvert;\n minAmountToConvert = minAmountToConvert_;\n emit MinAmountToConvertUpdated(oldMinAmountToConvert, minAmountToConvert_);\n }\n\n /**\n * @notice Swap array of pool assets into base asset's tokens of at least a minimum amount\n * @param markets Array of vTokens whose assets to swap for base asset\n * @param amountsOutMin Minimum amount to receive for swap\n * @param paths A path consisting of PCS token pairs for each swap\n * @param deadline Deadline for the swap\n * @return Number of swapped tokens\n * @custom:error ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured\n */\n function swapPoolsAssets(\n address[] calldata markets,\n uint256[] calldata amountsOutMin,\n address[][] calldata paths,\n uint256 deadline\n ) external override returns (uint256) {\n _checkAccessAllowed(\"swapPoolsAssets(address[],uint256[],address[][])\");\n require(deadline >= block.timestamp, \"Risk fund: deadline passed\");\n address poolRegistry_ = poolRegistry;\n ensureNonzeroAddress(poolRegistry_);\n require(markets.length == amountsOutMin.length, \"Risk fund: markets and amountsOutMin are unequal lengths\");\n require(markets.length == paths.length, \"Risk fund: markets and paths are unequal lengths\");\n\n uint256 totalAmount;\n uint256 marketsCount = markets.length;\n\n _ensureMaxLoops(marketsCount);\n\n for (uint256 i; i < marketsCount; ++i) {\n address comptroller = address(VToken(markets[i]).comptroller());\n\n PoolRegistry.VenusPool memory pool = PoolRegistry(poolRegistry_).getPoolByComptroller(comptroller);\n require(pool.comptroller == comptroller, \"comptroller doesn't exist pool registry\");\n require(Comptroller(comptroller).isMarketListed(VToken(markets[i])), \"market is not listed\");\n\n uint256 swappedTokens = _swapAsset(VToken(markets[i]), comptroller, amountsOutMin[i], paths[i]);\n poolsAssetsReserves[comptroller][convertibleBaseAsset] += swappedTokens;\n assetsReserves[convertibleBaseAsset] += swappedTokens;\n totalAmount = totalAmount + swappedTokens;\n }\n\n emit SwappedPoolsAssets(markets, amountsOutMin, totalAmount);\n\n return totalAmount;\n }\n\n /**\n * @notice Transfer tokens for auction.\n * @param comptroller Comptroller of the pool.\n * @param amount Amount to be transferred to auction contract.\n * @return Number reserved tokens.\n */\n function transferReserveForAuction(address comptroller, uint256 amount) external override returns (uint256) {\n address shortfall_ = shortfall;\n require(msg.sender == shortfall_, \"Risk fund: Only callable by Shortfall contract\");\n require(\n amount <= poolsAssetsReserves[comptroller][convertibleBaseAsset],\n \"Risk Fund: Insufficient pool reserve.\"\n );\n unchecked {\n poolsAssetsReserves[comptroller][convertibleBaseAsset] =\n poolsAssetsReserves[comptroller][convertibleBaseAsset] -\n amount;\n }\n unchecked {\n assetsReserves[convertibleBaseAsset] = assetsReserves[convertibleBaseAsset] - amount;\n }\n IERC20Upgradeable(convertibleBaseAsset).safeTransfer(shortfall_, amount);\n\n emit TransferredReserveForAuction(comptroller, amount);\n\n return amount;\n }\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Get the Amount of the Base asset in the risk fund for the specific pool.\n * @param comptroller Comptroller address(pool).\n * @return Base Asset's reserve in risk fund.\n */\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256) {\n require(ComptrollerInterface(comptroller).isComptroller(), \"Risk Fund: Comptroller address invalid\");\n return poolsAssetsReserves[comptroller][convertibleBaseAsset];\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund.\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n */\n function updateAssetsState(address comptroller, address asset) public override(IRiskFund, ReserveHelpers) {\n super.updateAssetsState(comptroller, asset);\n }\n\n /**\n * @dev Swap single asset to base asset.\n * @param vToken VToken\n * @param comptroller Comptroller address\n * @param amountOutMin Minimum amount to receive for swap\n * @param path A path for the swap consisting of PCS token pairs\n * @return Number of swapped tokens.\n */\n function _swapAsset(\n VToken vToken,\n address comptroller,\n uint256 amountOutMin,\n address[] calldata path\n ) internal returns (uint256) {\n require(amountOutMin != 0, \"RiskFund: amountOutMin must be greater than 0 to swap vToken\");\n require(amountOutMin >= minAmountToConvert, \"RiskFund: amountOutMin should be greater than minAmountToConvert\");\n uint256 totalAmount;\n\n address underlyingAsset = vToken.underlying();\n address convertibleBaseAsset_ = convertibleBaseAsset;\n uint256 balanceOfUnderlyingAsset = poolsAssetsReserves[comptroller][underlyingAsset];\n\n ComptrollerViewInterface(comptroller).oracle().updatePrice(address(vToken));\n\n uint256 underlyingAssetPrice = ComptrollerViewInterface(comptroller).oracle().getUnderlyingPrice(\n address(vToken)\n );\n\n if (balanceOfUnderlyingAsset > 0) {\n Exp memory oraclePrice = Exp({ mantissa: underlyingAssetPrice });\n uint256 amountInUsd = mul_ScalarTruncate(oraclePrice, balanceOfUnderlyingAsset);\n\n if (amountInUsd >= minAmountToConvert) {\n assetsReserves[underlyingAsset] -= balanceOfUnderlyingAsset;\n poolsAssetsReserves[comptroller][underlyingAsset] -= balanceOfUnderlyingAsset;\n\n if (underlyingAsset != convertibleBaseAsset_) {\n require(path[0] == underlyingAsset, \"RiskFund: swap path must start with the underlying asset\");\n require(\n path[path.length - 1] == convertibleBaseAsset_,\n \"RiskFund: finally path must be convertible base asset\"\n );\n address pancakeSwapRouter_ = pancakeSwapRouter;\n IERC20Upgradeable(underlyingAsset).approve(pancakeSwapRouter_, 0);\n IERC20Upgradeable(underlyingAsset).approve(pancakeSwapRouter_, balanceOfUnderlyingAsset);\n uint256[] memory amounts = IPancakeswapV2Router(pancakeSwapRouter_).swapExactTokensForTokens(\n balanceOfUnderlyingAsset,\n amountOutMin,\n path,\n address(this),\n block.timestamp\n );\n totalAmount = amounts[path.length - 1];\n } else {\n totalAmount = balanceOfUnderlyingAsset;\n }\n }\n }\n\n return totalAmount;\n }\n}\n" + }, + "contracts/Shortfall/IShortfall.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title IShortfall\n * @author Venus\n * @notice Interface implemented by `Shortfall`.\n */\ninterface IShortfall {\n function convertibleBaseAsset() external returns (address);\n}\n" + }, + "contracts/Shortfall/Shortfall.sol": { + "content": "/// @notice SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { ReentrancyGuardUpgradeable } from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { IRiskFund } from \"../RiskFund/IRiskFund.sol\";\nimport { IShortfall } from \"./IShortfall.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\nimport { TokenDebtTracker } from \"../lib/TokenDebtTracker.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\nimport { EXP_SCALE } from \"../lib/constants.sol\";\n\n/**\n * @title Shortfall\n * @author Venus\n * @notice Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset`\n * is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value.\n * This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner\n * is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise,\n * if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the\n * risk fund in exchange for paying off all the pool's bad debt.\n */\ncontract Shortfall is\n Ownable2StepUpgradeable,\n AccessControlledV8,\n ReentrancyGuardUpgradeable,\n TokenDebtTracker,\n IShortfall\n{\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /// @notice Type of auction\n enum AuctionType {\n LARGE_POOL_DEBT,\n LARGE_RISK_FUND\n }\n\n /// @notice Status of auction\n enum AuctionStatus {\n NOT_STARTED,\n STARTED,\n ENDED\n }\n\n /// @notice Auction metadata\n struct Auction {\n uint256 startBlock;\n AuctionType auctionType;\n AuctionStatus status;\n VToken[] markets;\n uint256 seizedRiskFund;\n address highestBidder;\n uint256 highestBidBps;\n uint256 highestBidBlock;\n uint256 startBidBps;\n mapping(VToken => uint256) marketDebt;\n mapping(VToken => uint256) bidAmount;\n }\n\n /// @dev Max basis points i.e., 100%\n uint256 private constant MAX_BPS = 10000;\n\n uint256 private constant DEFAULT_NEXT_BIDDER_BLOCK_LIMIT = 100;\n\n uint256 private constant DEFAULT_WAIT_FOR_FIRST_BIDDER = 100;\n\n uint256 private constant DEFAULT_INCENTIVE_BPS = 1000; // 10%\n\n /// @notice Pool registry address\n address public poolRegistry;\n\n /// @notice Risk fund address\n IRiskFund public riskFund;\n\n /// @notice Minimum USD debt in pool for shortfall to trigger\n uint256 public minimumPoolBadDebt;\n\n /// @notice Incentive to auction participants, initial value set to 1000 or 10%\n uint256 public incentiveBps;\n\n /// @notice Time to wait for next bidder. initially waits for 10 blocks\n uint256 public nextBidderBlockLimit;\n\n /// @notice Boolean of if auctions are paused\n bool public auctionsPaused;\n\n /// @notice Time to wait for first bidder. initially waits for 100 blocks\n uint256 public waitForFirstBidder;\n\n /// @notice base asset contract address\n address public convertibleBaseAsset;\n\n /// @notice Auctions for each pool\n mapping(address => Auction) public auctions;\n\n /// @notice Emitted when a auction starts\n event AuctionStarted(\n address indexed comptroller,\n uint256 auctionStartBlock,\n AuctionType auctionType,\n VToken[] markets,\n uint256[] marketsDebt,\n uint256 seizedRiskFund,\n uint256 startBidBps\n );\n\n /// @notice Emitted when a bid is placed\n event BidPlaced(address indexed comptroller, uint256 auctionStartBlock, uint256 bidBps, address indexed bidder);\n\n /// @notice Emitted when a auction is completed\n event AuctionClosed(\n address indexed comptroller,\n uint256 auctionStartBlock,\n address indexed highestBidder,\n uint256 highestBidBps,\n uint256 seizedRiskFind,\n VToken[] markets,\n uint256[] marketDebt\n );\n\n /// @notice Emitted when a auction is restarted\n event AuctionRestarted(address indexed comptroller, uint256 auctionStartBlock);\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @notice Emitted when minimum pool bad debt is updated\n event MinimumPoolBadDebtUpdated(uint256 oldMinimumPoolBadDebt, uint256 newMinimumPoolBadDebt);\n\n /// @notice Emitted when wait for first bidder block count is updated\n event WaitForFirstBidderUpdated(uint256 oldWaitForFirstBidder, uint256 newWaitForFirstBidder);\n\n /// @notice Emitted when next bidder block limit is updated\n event NextBidderBlockLimitUpdated(uint256 oldNextBidderBlockLimit, uint256 newNextBidderBlockLimit);\n\n /// @notice Emitted when incentiveBps is updated\n event IncentiveBpsUpdated(uint256 oldIncentiveBps, uint256 newIncentiveBps);\n\n /// @notice Emitted when auctions are paused\n event AuctionsPaused(address sender);\n\n /// @notice Emitted when auctions are unpaused\n event AuctionsResumed(address sender);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initialize the shortfall contract\n * @param convertibleBaseAsset_ Asset to swap the funds to\n * @param riskFund_ RiskFund contract address\n * @param minimumPoolBadDebt_ Minimum bad debt in base asset for a pool to start auction\n * @param accessControlManager_ AccessControlManager contract address\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\n */\n function initialize(\n address convertibleBaseAsset_,\n IRiskFund riskFund_,\n uint256 minimumPoolBadDebt_,\n address accessControlManager_\n ) external initializer {\n ensureNonzeroAddress(convertibleBaseAsset_);\n ensureNonzeroAddress(address(riskFund_));\n require(minimumPoolBadDebt_ != 0, \"invalid minimum pool bad debt\");\n\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n __ReentrancyGuard_init();\n __TokenDebtTracker_init();\n minimumPoolBadDebt = minimumPoolBadDebt_;\n convertibleBaseAsset = convertibleBaseAsset_;\n riskFund = riskFund_;\n waitForFirstBidder = DEFAULT_WAIT_FOR_FIRST_BIDDER;\n nextBidderBlockLimit = DEFAULT_NEXT_BIDDER_BLOCK_LIMIT;\n incentiveBps = DEFAULT_INCENTIVE_BPS;\n auctionsPaused = false;\n }\n\n /**\n * @notice Place a bid greater than the previous in an ongoing auction\n * @param comptroller Comptroller address of the pool\n * @param bidBps The bid percent of the risk fund or bad debt depending on auction type\n * @param auctionStartBlock The block number when auction started\n * @custom:event Emits BidPlaced event on success\n */\n function placeBid(\n address comptroller,\n uint256 bidBps,\n uint256 auctionStartBlock\n ) external nonReentrant {\n Auction storage auction = auctions[comptroller];\n\n require(auction.startBlock == auctionStartBlock, \"auction has been restarted\");\n require(_isStarted(auction), \"no on-going auction\");\n require(!_isStale(auction), \"auction is stale, restart it\");\n require(bidBps > 0, \"basis points cannot be zero\");\n require(bidBps <= MAX_BPS, \"basis points cannot be more than 10000\");\n require(\n (auction.auctionType == AuctionType.LARGE_POOL_DEBT &&\n ((auction.highestBidder != address(0) && bidBps > auction.highestBidBps) ||\n (auction.highestBidder == address(0) && bidBps >= auction.startBidBps))) ||\n (auction.auctionType == AuctionType.LARGE_RISK_FUND &&\n ((auction.highestBidder != address(0) && bidBps < auction.highestBidBps) ||\n (auction.highestBidder == address(0) && bidBps <= auction.startBidBps))),\n \"your bid is not the highest\"\n );\n\n uint256 marketsCount = auction.markets.length;\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = VToken(address(auction.markets[i]));\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\n\n if (auction.highestBidder != address(0)) {\n _transferOutOrTrackDebt(erc20, auction.highestBidder, auction.bidAmount[auction.markets[i]]);\n }\n uint256 balanceBefore = erc20.balanceOf(address(this));\n\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\n uint256 currentBidAmount = ((auction.marketDebt[auction.markets[i]] * bidBps) / MAX_BPS);\n erc20.safeTransferFrom(msg.sender, address(this), currentBidAmount);\n } else {\n erc20.safeTransferFrom(msg.sender, address(this), auction.marketDebt[auction.markets[i]]);\n }\n\n uint256 balanceAfter = erc20.balanceOf(address(this));\n auction.bidAmount[auction.markets[i]] = balanceAfter - balanceBefore;\n }\n\n auction.highestBidder = msg.sender;\n auction.highestBidBps = bidBps;\n auction.highestBidBlock = block.number;\n\n emit BidPlaced(comptroller, auction.startBlock, bidBps, msg.sender);\n }\n\n /**\n * @notice Close an auction\n * @param comptroller Comptroller address of the pool\n * @custom:event Emits AuctionClosed event on successful close\n */\n function closeAuction(address comptroller) external nonReentrant {\n Auction storage auction = auctions[comptroller];\n\n require(_isStarted(auction), \"no on-going auction\");\n require(\n block.number > auction.highestBidBlock + nextBidderBlockLimit && auction.highestBidder != address(0),\n \"waiting for next bidder. cannot close auction\"\n );\n\n uint256 marketsCount = auction.markets.length;\n uint256[] memory marketsDebt = new uint256[](marketsCount);\n\n auction.status = AuctionStatus.ENDED;\n\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = VToken(address(auction.markets[i]));\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\n\n uint256 balanceBefore = erc20.balanceOf(address(auction.markets[i]));\n erc20.safeTransfer(address(auction.markets[i]), auction.bidAmount[auction.markets[i]]);\n uint256 balanceAfter = erc20.balanceOf(address(auction.markets[i]));\n marketsDebt[i] = balanceAfter - balanceBefore;\n\n auction.markets[i].badDebtRecovered(marketsDebt[i]);\n }\n\n uint256 riskFundBidAmount;\n\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\n riskFundBidAmount = auction.seizedRiskFund;\n } else {\n riskFundBidAmount = (auction.seizedRiskFund * auction.highestBidBps) / MAX_BPS;\n }\n\n uint256 transferredAmount = riskFund.transferReserveForAuction(comptroller, riskFundBidAmount);\n IERC20Upgradeable(convertibleBaseAsset).safeTransfer(auction.highestBidder, riskFundBidAmount);\n\n emit AuctionClosed(\n comptroller,\n auction.startBlock,\n auction.highestBidder,\n auction.highestBidBps,\n transferredAmount,\n auction.markets,\n marketsDebt\n );\n }\n\n /**\n * @notice Start a auction when there is not currently one active\n * @param comptroller Comptroller address of the pool\n * @custom:event Emits AuctionStarted event on success\n * @custom:event Errors if auctions are paused\n */\n function startAuction(address comptroller) external {\n require(!auctionsPaused, \"Auctions are paused\");\n _startAuction(comptroller);\n }\n\n /**\n * @notice Restart an auction\n * @param comptroller Address of the pool\n * @custom:event Emits AuctionRestarted event on successful restart\n */\n function restartAuction(address comptroller) external {\n Auction storage auction = auctions[comptroller];\n\n require(!auctionsPaused, \"auctions are paused\");\n require(_isStarted(auction), \"no on-going auction\");\n require(_isStale(auction), \"you need to wait for more time for first bidder\");\n\n auction.status = AuctionStatus.ENDED;\n\n emit AuctionRestarted(comptroller, auction.startBlock);\n _startAuction(comptroller);\n }\n\n /**\n * @notice Update next bidder block limit which is used determine when an auction can be closed\n * @param _nextBidderBlockLimit New next bidder block limit\n * @custom:event Emits NextBidderBlockLimitUpdated on success\n * @custom:access Restricted to owner\n */\n function updateNextBidderBlockLimit(uint256 _nextBidderBlockLimit) external {\n _checkAccessAllowed(\"updateNextBidderBlockLimit(uint256)\");\n require(_nextBidderBlockLimit != 0, \"_nextBidderBlockLimit must not be 0\");\n uint256 oldNextBidderBlockLimit = nextBidderBlockLimit;\n nextBidderBlockLimit = _nextBidderBlockLimit;\n emit NextBidderBlockLimitUpdated(oldNextBidderBlockLimit, _nextBidderBlockLimit);\n }\n\n /**\n * @notice Updates the inventive BPS\n * @param _incentiveBps New incentive BPS\n * @custom:event Emits IncentiveBpsUpdated on success\n * @custom:access Restricted to owner\n */\n function updateIncentiveBps(uint256 _incentiveBps) external {\n _checkAccessAllowed(\"updateIncentiveBps(uint256)\");\n require(_incentiveBps != 0, \"incentiveBps must not be 0\");\n uint256 oldIncentiveBps = incentiveBps;\n incentiveBps = _incentiveBps;\n emit IncentiveBpsUpdated(oldIncentiveBps, _incentiveBps);\n }\n\n /**\n * @notice Update minimum pool bad debt to start auction\n * @param _minimumPoolBadDebt Minimum bad debt in BUSD for a pool to start auction\n * @custom:event Emits MinimumPoolBadDebtUpdated on success\n * @custom:access Restricted to owner\n */\n function updateMinimumPoolBadDebt(uint256 _minimumPoolBadDebt) external {\n _checkAccessAllowed(\"updateMinimumPoolBadDebt(uint256)\");\n uint256 oldMinimumPoolBadDebt = minimumPoolBadDebt;\n minimumPoolBadDebt = _minimumPoolBadDebt;\n emit MinimumPoolBadDebtUpdated(oldMinimumPoolBadDebt, _minimumPoolBadDebt);\n }\n\n /**\n * @notice Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted\n * @param _waitForFirstBidder New wait for first bidder block count\n * @custom:event Emits WaitForFirstBidderUpdated on success\n * @custom:access Restricted to owner\n */\n function updateWaitForFirstBidder(uint256 _waitForFirstBidder) external {\n _checkAccessAllowed(\"updateWaitForFirstBidder(uint256)\");\n uint256 oldWaitForFirstBidder = waitForFirstBidder;\n waitForFirstBidder = _waitForFirstBidder;\n emit WaitForFirstBidderUpdated(oldWaitForFirstBidder, _waitForFirstBidder);\n }\n\n /**\n * @notice Update the pool registry this shortfall supports\n * @dev After Pool Registry is deployed we need to set the pool registry address\n * @param poolRegistry_ Address of pool registry contract\n * @custom:event Emits PoolRegistryUpdated on success\n * @custom:access Restricted to owner\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function updatePoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Pause auctions. This disables starting new auctions but lets the current auction finishes\n * @custom:event Emits AuctionsPaused on success\n * @custom:error Errors is auctions are paused\n * @custom:access Restricted by ACM\n */\n function pauseAuctions() external {\n _checkAccessAllowed(\"pauseAuctions()\");\n require(!auctionsPaused, \"Auctions are already paused\");\n auctionsPaused = true;\n emit AuctionsPaused(msg.sender);\n }\n\n /**\n * @notice Resume paused auctions.\n * @custom:event Emits AuctionsResumed on success\n * @custom:error Errors is auctions are active\n * @custom:access Restricted by ACM\n */\n function resumeAuctions() external {\n _checkAccessAllowed(\"resumeAuctions()\");\n require(auctionsPaused, \"Auctions are not paused\");\n auctionsPaused = false;\n emit AuctionsResumed(msg.sender);\n }\n\n /**\n * @notice Start a auction when there is not currently one active\n * @param comptroller Comptroller address of the pool\n */\n function _startAuction(address comptroller) internal {\n PoolRegistryInterface.VenusPool memory pool = PoolRegistry(poolRegistry).getPoolByComptroller(comptroller);\n require(pool.comptroller == comptroller, \"comptroller doesn't exist pool registry\");\n\n Auction storage auction = auctions[comptroller];\n require(\n (auction.startBlock == 0 && auction.status == AuctionStatus.NOT_STARTED) ||\n auction.status == AuctionStatus.ENDED,\n \"auction is on-going\"\n );\n\n auction.highestBidBps = 0;\n auction.highestBidBlock = 0;\n\n uint256 marketsCount = auction.markets.length;\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = auction.markets[i];\n auction.marketDebt[vToken] = 0;\n }\n\n delete auction.markets;\n\n VToken[] memory vTokens = _getAllMarkets(comptroller);\n marketsCount = vTokens.length;\n ResilientOracleInterface priceOracle = _getPriceOracle(comptroller);\n uint256 poolBadDebt;\n\n uint256[] memory marketsDebt = new uint256[](marketsCount);\n auction.markets = new VToken[](marketsCount);\n\n for (uint256 i; i < marketsCount; ++i) {\n uint256 marketBadDebt = vTokens[i].badDebt();\n\n priceOracle.updatePrice(address(vTokens[i]));\n uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / EXP_SCALE;\n\n poolBadDebt = poolBadDebt + usdValue;\n auction.markets[i] = vTokens[i];\n auction.marketDebt[vTokens[i]] = marketBadDebt;\n marketsDebt[i] = marketBadDebt;\n }\n\n require(poolBadDebt >= minimumPoolBadDebt, \"pool bad debt is too low\");\n\n priceOracle.updateAssetPrice(riskFund.convertibleBaseAsset());\n uint256 riskFundBalance = (priceOracle.getPrice(riskFund.convertibleBaseAsset()) *\n riskFund.getPoolsBaseAssetReserves(comptroller)) / EXP_SCALE;\n uint256 remainingRiskFundBalance = riskFundBalance;\n uint256 badDebtPlusIncentive = poolBadDebt + ((poolBadDebt * incentiveBps) / MAX_BPS);\n if (badDebtPlusIncentive >= riskFundBalance) {\n auction.startBidBps =\n (MAX_BPS * MAX_BPS * remainingRiskFundBalance) /\n (poolBadDebt * (MAX_BPS + incentiveBps));\n remainingRiskFundBalance = 0;\n auction.auctionType = AuctionType.LARGE_POOL_DEBT;\n } else {\n uint256 maxSeizeableRiskFundBalance = badDebtPlusIncentive;\n\n remainingRiskFundBalance = remainingRiskFundBalance - maxSeizeableRiskFundBalance;\n auction.auctionType = AuctionType.LARGE_RISK_FUND;\n auction.startBidBps = MAX_BPS;\n }\n\n auction.seizedRiskFund = riskFundBalance - remainingRiskFundBalance;\n auction.startBlock = block.number;\n auction.status = AuctionStatus.STARTED;\n auction.highestBidder = address(0);\n\n emit AuctionStarted(\n comptroller,\n auction.startBlock,\n auction.auctionType,\n auction.markets,\n marketsDebt,\n auction.seizedRiskFund,\n auction.startBidBps\n );\n }\n\n /**\n * @dev Returns the price oracle of the pool\n * @param comptroller Address of the pool's comptroller\n * @return oracle The pool's price oracle\n */\n function _getPriceOracle(address comptroller) internal view returns (ResilientOracleInterface) {\n return ResilientOracleInterface(ComptrollerViewInterface(comptroller).oracle());\n }\n\n /**\n * @dev Returns all markets of the pool\n * @param comptroller Address of the pool's comptroller\n * @return markets The pool's markets as VToken array\n */\n function _getAllMarkets(address comptroller) internal view returns (VToken[] memory) {\n return ComptrollerInterface(comptroller).getAllMarkets();\n }\n\n /**\n * @dev Checks if the auction has started\n * @param auction The auction to query the status for\n * @return True if the auction has started\n */\n function _isStarted(Auction storage auction) internal view returns (bool) {\n return auction.startBlock != 0 && auction.status == AuctionStatus.STARTED;\n }\n\n /**\n * @dev Checks if the auction is stale, i.e. there's no bidder and the auction\n * was started more than waitForFirstBidder blocks ago.\n * @param auction The auction to query the status for\n * @return True if the auction is stale\n */\n function _isStale(Auction storage auction) internal view returns (bool) {\n bool noBidder = auction.highestBidder == address(0);\n return noBidder && (block.number > auction.startBlock + waitForFirstBidder);\n }\n}\n" + }, + "contracts/test/ComptrollerHarness.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { Comptroller } from \"../Comptroller.sol\";\n\ncontract ComptrollerHarness is Comptroller {\n uint256 public blockNumber;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address _poolRegistry) Comptroller(_poolRegistry) {}\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\ncontract EchoTypesComptroller {\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(uint256[] memory u) public pure returns (uint256[] memory) {\n return u;\n }\n\n function reverty() public pure {\n require(false, \"gotcha sucka\");\n }\n}\n" + }, + "contracts/test/ComptrollerScenario.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { VToken } from \"../VToken.sol\";\n\ncontract ComptrollerScenario is Comptroller {\n uint256 public blockNumber;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address _poolRegistry) Comptroller(_poolRegistry) {}\n\n function fastForward(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 unlist(VToken vToken) public {\n markets[address(vToken)].isListed = false;\n }\n\n function membershipLength(VToken vToken) public view returns (uint256) {\n return accountAssets[address(vToken)].length;\n }\n}\n" + }, + "contracts/test/ERC20.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { SafeMath } from \"./SafeMath.sol\";\n\ninterface ERC20Base {\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 approve(address spender, uint256 value) external returns (bool);\n\n function totalSupply() external view returns (uint256);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function balanceOf(address who) external view returns (uint256);\n}\n\nabstract contract ERC20 is ERC20Base {\n function transfer(address to, uint256 value) external virtual returns (bool);\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external virtual returns (bool);\n}\n\nabstract contract ERC20NS is ERC20Base {\n function transfer(address to, uint256 value) external virtual;\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external virtual;\n}\n\n/**\n * @title Standard ERC20 token\n * @dev Implementation of the basic standard token.\n * See https://github.com/ethereum/EIPs/issues/20\n */\ncontract StandardToken is ERC20 {\n using SafeMath for uint256;\n\n string public name;\n string public symbol;\n uint8 public decimals;\n uint256 public override totalSupply;\n mapping(address => mapping(address => uint256)) public override allowance;\n mapping(address => uint256) public override balanceOf;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) {\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 virtual override 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(\n address src,\n address dst,\n uint256 amount\n ) external virtual override 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 virtual override 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 ERC20 token\n * @dev Version of ERC20 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 ERC20NS {\n using SafeMath for uint256;\n\n string public name;\n uint8 public decimals;\n string public symbol;\n uint256 public override totalSupply;\n mapping(address => mapping(address => uint256)) public override allowance;\n mapping(address => uint256) public override balanceOf;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) {\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 override {\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(\n address src,\n address dst,\n uint256 amount\n ) external override {\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 override returns (bool) {\n allowance[msg.sender][_spender] = amount;\n emit Approval(msg.sender, _spender, amount);\n return true;\n }\n}\n\ncontract ERC20Harness is StandardToken {\n using SafeMath for uint256;\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 )\n StandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol)\n /* solhint-disable-next-line no-empty-blocks */\n {\n\n }\n\n function transfer(address dst, uint256 amount) external override 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(\n address src,\n address dst,\n uint256 amount\n ) external override 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 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, uint256 _amount) public {\n balanceOf[_account] = _amount;\n }\n}\n" + }, + "contracts/test/EvilToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { FaucetToken } from \"./FaucetToken.sol\";\nimport { SafeMath } from \"./SafeMath.sol\";\n\n/**\n * @title The Compound Evil Test Token\n * @author Compound\n * @notice A simple test token that fails certain operations\n */\ncontract EvilToken is FaucetToken {\n using SafeMath for uint256;\n\n bool public fail;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) 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 override 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(\n address src,\n address dst,\n uint256 amount\n ) external override 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/FaucetToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { StandardToken, NonStandardToken } from \"./ERC20.sol\";\nimport { SafeMath } from \"./SafeMath.sol\";\n\n/**\n * @title The Compound Faucet Test Token\n * @author Compound\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 )\n StandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol)\n /* solhint-disable-next-line no-empty-blocks */\n {\n\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\n/**\n * @title The Compound Faucet Test Token (non-standard)\n * @author Compound\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 )\n NonStandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol)\n /* solhint-disable-next-line no-empty-blocks */\n {\n\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\n/**\n * @title The Compound Faucet Re-Entrant Test Token\n * @author Compound\n * @notice A test token that is malicious and tries to re-enter callers\n */\ncontract FaucetTokenReEntrantHarness {\n using SafeMath for uint256;\n\n string public name;\n string public symbol;\n uint8 public decimals;\n uint256 private totalSupply_;\n mapping(address => mapping(address => uint256)) private allowance_;\n mapping(address => uint256) private balanceOf_;\n\n bytes public reEntryCallData;\n string public reEntryFun;\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 modifier reEnter(string memory funName) {\n string memory _reEntryFun = reEntryFun;\n if (compareStrings(_reEntryFun, funName)) {\n reEntryFun = \"\"; // Clear re-entry fun\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = msg.sender.call(reEntryCallData);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(success, 0) {\n revert(add(returndata, 0x20), returndatasize())\n }\n }\n }\n\n _;\n }\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 ) {\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 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(\n address owner,\n address spender,\n uint256 amount\n ) internal {\n require(spender != address(0), \"FaucetToken: approve to the zero address\");\n require(owner != address(0), \"FaucetToken: approve from the zero address\");\n allowance_[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _transfer(\n address src,\n address dst,\n uint256 amount\n ) internal {\n require(dst != address(0), \"FaucetToken: transfer to the zero address\");\n balanceOf_[src] = balanceOf_[src].sub(amount);\n balanceOf_[dst] = balanceOf_[dst].add(amount);\n emit Transfer(src, dst, amount);\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/FeeToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { FaucetToken } from \"./FaucetToken.sol\";\nimport { SafeMath } from \"./SafeMath.sol\";\n\n/**\n * @title Fee Token\n * @author Compound\n * @notice A simple test token that charges fees on transfer. Used to mock USDT.\n */\ncontract FeeToken is FaucetToken {\n using SafeMath for uint256;\n\n uint256 public basisPointFee;\n address public owner;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol,\n uint256 _basisPointFee,\n address _owner\n ) FaucetToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {\n basisPointFee = _basisPointFee;\n owner = _owner;\n }\n\n function transfer(address dst, uint256 amount) public override returns (bool) {\n uint256 fee = amount.mul(basisPointFee).div(10000);\n uint256 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(\n address src,\n address dst,\n uint256 amount\n ) public override returns (bool) {\n uint256 fee = amount.mul(basisPointFee).div(10000);\n uint256 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/HarnessMaxLoopsLimitHelper.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { MaxLoopsLimitHelper } from \"../MaxLoopsLimitHelper.sol\";\n\ncontract HarnessMaxLoopsLimitHelper is MaxLoopsLimitHelper {\n function setMaxLoopsLimit(uint256 limit) external {\n _setMaxLoopsLimit(limit);\n }\n\n function ensureMaxLoops(uint256 limit) external view {\n _ensureMaxLoops(limit);\n }\n}\n" + }, + "contracts/test/lib/TokenDebtTrackerHarness.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { TokenDebtTracker } from \"../../lib/TokenDebtTracker.sol\";\n\ncontract TokenDebtTrackerHarness is TokenDebtTracker {\n function initialize() external initializer {\n __TokenDebtTracker_init();\n }\n\n function addTokenDebt(\n IERC20Upgradeable token,\n address user,\n uint256 amount\n ) external {\n tokenDebt[token][user] += amount;\n totalTokenDebt[token] += amount;\n }\n\n function transferOutOrTrackDebt(\n IERC20Upgradeable token,\n address user,\n uint256 amount\n ) external {\n _transferOutOrTrackDebt(token, user, amount);\n }\n\n function transferOutOrTrackDebtSkippingBalanceCheck(\n IERC20Upgradeable token,\n address user,\n uint256 amount\n ) external {\n _transferOutOrTrackDebtSkippingBalanceCheck(token, user, amount);\n }\n}\n" + }, + "contracts/test/MockDeflationaryToken.sol": { + "content": "pragma solidity 0.8.13;\n\ncontract MockDeflatingToken {\n string public constant NAME = \"Deflating Test Token\";\n string public constant SYMBOL = \"DTT\";\n uint8 public constant DECIMALS = 18;\n uint256 public totalSupply;\n mapping(address => uint256) public balanceOf;\n mapping(address => mapping(address => uint256)) 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 => uint256) public nonces;\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n constructor(uint256 _totalSupply) {\n uint256 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 approve(address spender, uint256 value) external returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transfer(address to, uint256 value) external returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool) {\n if (allowance[from][msg.sender] != type(uint256).max) {\n allowance[from][msg.sender] = allowance[from][msg.sender] - value;\n }\n _transfer(from, to, value);\n return true;\n }\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) 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 function _mint(address to, uint256 value) internal {\n totalSupply = totalSupply + value;\n balanceOf[to] = balanceOf[to] + value;\n emit Transfer(address(0), to, value);\n }\n\n function _burn(address from, uint256 value) internal {\n balanceOf[from] = balanceOf[from] - value;\n totalSupply = totalSupply - value;\n emit Transfer(from, address(0), value);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 value\n ) private {\n allowance[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 value\n ) private {\n uint256 burnAmount = value / 100;\n _burn(from, burnAmount);\n uint256 transferAmount = value - burnAmount;\n balanceOf[from] = balanceOf[from] - transferAmount;\n balanceOf[to] = balanceOf[to] + transferAmount;\n emit Transfer(from, to, transferAmount);\n }\n}\n" + }, + "contracts/test/Mocks/MockPriceOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { BinanceOracle } from \"@venusprotocol/oracle/contracts/oracles/BinanceOracle.sol\";\nimport { ChainlinkOracle } from \"@venusprotocol/oracle/contracts/oracles/ChainlinkOracle.sol\";\n\nimport { VToken } from \"../../VToken.sol\";\n\ncontract MockPriceOracle is ResilientOracleInterface {\n mapping(address => uint256) public assetPrices;\n\n //set price in 6 decimal precision\n // solhint-disable-next-line no-empty-blocks\n constructor() {}\n\n function setPrice(address asset, uint256 price) external {\n assetPrices[asset] = price;\n }\n\n // solhint-disable-next-line no-empty-blocks\n function updatePrice(address vToken) external override {}\n\n // solhint-disable-next-line no-empty-blocks\n function updateAssetPrice(address asset) external override {}\n\n function getPrice(address asset) external view returns (uint256) {\n return assetPrices[asset];\n }\n\n //https://compound.finance/docs/prices\n function getUnderlyingPrice(address vToken) public view override returns (uint256) {\n return assetPrices[VToken(vToken).underlying()];\n }\n}\n" + }, + "contracts/test/Mocks/MockToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n uint8 private immutable _decimals;\n\n constructor(\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) ERC20(name_, symbol_) {\n _decimals = decimals_;\n }\n\n function faucet(uint256 amount) external {\n _mint(msg.sender, amount);\n }\n\n function decimals() public view virtual override returns (uint8) {\n return _decimals;\n }\n}\n" + }, + "contracts/test/SafeMath.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\n// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol\n// Subject to the MIT license.\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 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 uint256 c;\n unchecked {\n c = a + b;\n }\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting with custom message on overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n uint256 c;\n unchecked {\n c = a + b;\n }\n require(c >= a, errorMessage);\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot underflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction underflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot underflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) 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 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;\n unchecked {\n c = a * b;\n }\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) 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;\n unchecked {\n c = a * b;\n }\n require(c / a == b, errorMessage);\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers.\n * Reverts on 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.\n * Reverts with custom message on 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(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) 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(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/test/UpgradedVToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { AccessControlManager } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol\";\n\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { InterestRateModel } from \"../InterestRateModel.sol\";\n\n/**\n * @title Venus's VToken Contract\n * @notice VTokens which wrap an EIP-20 underlying and are immutable\n * @author Venus\n */\ncontract UpgradedVToken is VToken {\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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param riskManagement Addresses of risk fund contracts\n */\n\n /// @notice We added this new function to test contract upgrade\n function version() external pure returns (uint256) {\n return 2;\n }\n\n function initializeV2(\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 accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) public reinitializer(2) {\n super._initialize(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_,\n accessControlManager_,\n riskManagement,\n reserveFactorMantissa_\n );\n }\n\n function getTokenUnderlying() public view returns (address) {\n return underlying;\n }\n}\n" + }, + "contracts/test/VTokenHarness.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { AccessControlManager } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol\";\n\nimport { VToken } from \"../VToken.sol\";\nimport { InterestRateModel } from \"../InterestRateModel.sol\";\n\ncontract VTokenHarness is VToken {\n uint256 public blockNumber;\n uint256 public harnessExchangeRate;\n bool public harnessExchangeRateStored;\n\n mapping(address => bool) public failTransferToAddresses;\n\n function harnessSetAccrualBlockNumber(uint256 accrualBlockNumber_) external {\n accrualBlockNumber = accrualBlockNumber_;\n }\n\n function harnessSetBlockNumber(uint256 newBlockNumber) external {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint256 blocks) external {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint256 amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetTotalSupply(uint256 totalSupply_) external {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint256 totalBorrows_) external {\n totalBorrows = totalBorrows_;\n }\n\n function harnessSetTotalReserves(uint256 totalReserves_) external {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(\n uint256 totalSupply_,\n uint256 totalBorrows_,\n uint256 totalReserves_\n ) external {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint256 exchangeRate) external {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address to_, bool fail_) external {\n failTransferToAddresses[to_] = fail_;\n }\n\n function harnessMintFresh(address account, uint256 mintAmount) external {\n super._mintFresh(account, account, mintAmount);\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint256 vTokenAmount,\n uint256 underlyingAmount\n ) external {\n super._redeemFresh(account, vTokenAmount, underlyingAmount);\n }\n\n function harnessSetAccountBorrows(\n address account,\n uint256 principal,\n uint256 interestIndex\n ) external {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint256 borrowIndex_) external {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint256 borrowAmount) external {\n _borrowFresh(account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(\n address payer,\n address account,\n uint256 repayAmount\n ) external {\n _repayBorrowFresh(payer, account, repayAmount);\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VToken vTokenCollateral,\n bool skipLiquidityCheck\n ) external {\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\n }\n\n function harnessReduceReservesFresh(uint256 amount) external {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint256 newReserveFactorMantissa) external {\n _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) external {\n _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessAccountBorrows(address account) external view returns (uint256 principal, uint256 interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function getBorrowRateMaxMantissa() external pure returns (uint256) {\n return MAX_BORROW_RATE_MANTISSA;\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallPreBorrowHook(uint256 amount) public {\n comptroller.preBorrowHook(address(this), msg.sender, amount);\n }\n\n function _doTransferOut(address to, uint256 amount) internal override {\n require(failTransferToAddresses[to] == false, \"HARNESS_TOKEN_TRANSFER_OUT_FAILED\");\n return super._doTransferOut(to, amount);\n }\n\n function _exchangeRateStored() internal view override returns (uint256) {\n if (harnessExchangeRateStored) {\n return harnessExchangeRate;\n }\n return super._exchangeRateStored();\n }\n\n function _getBlockNumber() internal view override returns (uint256) {\n return blockNumber;\n }\n}\n" + }, + "contracts/VToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { VTokenInterface } from \"./VTokenInterfaces.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"./ComptrollerInterface.sol\";\nimport { TokenErrorReporter } from \"./ErrorReporter.sol\";\nimport { InterestRateModel } from \"./InterestRateModel.sol\";\nimport { ExponentialNoError } from \"./ExponentialNoError.sol\";\nimport { IProtocolShareReserve } from \"./RiskFund/IProtocolShareReserve.sol\";\nimport { ensureNonzeroAddress } from \"./lib/validators.sol\";\n\n/**\n * @title VToken\n * @author Venus\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\n * the pool. The main actions a user regularly interacts with in a market are:\n\n- mint/redeem of vTokens;\n- transfer of vTokens;\n- borrow/repay a loan on an underlying asset;\n- liquidate a borrow or liquidate/heal an account.\n\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\n * a user may borrow up to a portion of their collateral determined by the market’s collateral factor. However, if their borrowed amount exceeds an amount\n * calculated using the market’s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\n * pay off interest accrued on the borrow.\n * \n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\n * Both functions settle all of an account’s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\n */\ncontract VToken is\n Ownable2StepUpgradeable,\n AccessControlledV8,\n VTokenInterface,\n ExponentialNoError,\n TokenErrorReporter\n{\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\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 /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param accessControlManager_ AccessControlManager contract address\n * @param riskManagement Addresses of risk & income related contracts\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\n */\n function initialize(\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 admin_,\n address accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) external initializer {\n ensureNonzeroAddress(admin_);\n\n // Initialize the market\n _initialize(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_,\n accessControlManager_,\n riskManagement,\n reserveFactorMantissa_\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 * @return success True if the transfer succeeded, reverts otherwise\n * @custom:event Emits Transfer event on success\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\n * @custom:access Not restricted\n */\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\n * @return success True if the transfer succeeded, reverts otherwise\n * @custom:event Emits Transfer event on success\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\n * @custom:access Not restricted\n */\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) external override nonReentrant returns (bool) {\n _transferTokens(msg.sender, src, dst, amount);\n return true;\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 (uint256.max means infinite)\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function approve(address spender, uint256 amount) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n transferAllowances[src][spender] = amount;\n emit Approval(src, spender, amount);\n return true;\n }\n\n /**\n * @notice Increase approval for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param addedValue The number of additional tokens spender can transfer\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n uint256 newAllowance = transferAllowances[src][spender];\n newAllowance += addedValue;\n transferAllowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n return true;\n }\n\n /**\n * @notice Decreases approval for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param subtractedValue The number of tokens to remove from total approval\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n uint256 currentAllowance = transferAllowances[src][spender];\n require(currentAllowance >= subtractedValue, \"decreased allowance below zero\");\n unchecked {\n currentAllowance -= subtractedValue;\n }\n\n transferAllowances[src][spender] = currentAllowance;\n\n emit Approval(src, spender, currentAllowance);\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 amount The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external override returns (uint256) {\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return totalBorrows The total borrows with interest\n */\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\n accrueInterest();\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 borrowBalance The calculated balance\n */\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\n accrueInterest();\n return _borrowBalanceStored(account);\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n _mintFresh(msg.sender, msg.sender, mintAmount);\n return NO_ERROR;\n }\n\n /**\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param minter User whom the supply will be attributed to\n * @param mintAmount The amount of the underlying asset to supply\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\n */\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\n ensureNonzeroAddress(minter);\n\n accrueInterest();\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n _mintFresh(msg.sender, minter, mintAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\n * @custom:access Not restricted\n */\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\n _redeemFresh(msg.sender, redeemTokens, 0);\n return NO_ERROR;\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 receive from redeeming vTokens\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n */\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\n _redeemFresh(msg.sender, 0, redeemAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Borrow event; may emit AccrueInterest\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\n * @custom:access Not restricted\n */\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\n _borrowFresh(msg.sender, borrowAmount);\n return NO_ERROR;\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\n return NO_ERROR;\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, or type(uint256).max for the full outstanding amount\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\n * @custom:access Not restricted\n */\n function liquidateBorrow(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external override returns (uint256) {\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\n return NO_ERROR;\n }\n\n /**\n * @notice sets protocol share accumulated from liquidations\n * @dev must be equal or less than liquidation incentive - 1\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\n * @custom:event Emits NewProtocolSeizeShare event on success\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\n * @custom:access Controlled by AccessControlManager\n */\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\n _checkAccessAllowed(\"setProtocolSeizeShare(uint256)\");\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\n revert ProtocolSeizeShareTooBig();\n }\n\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\n * @custom:access Controlled by AccessControlManager\n */\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\n _checkAccessAllowed(\"setReserveFactor(uint256)\");\n\n accrueInterest();\n _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\n * @param reduceAmount Amount of reduction to reserves\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\n * @custom:access Not restricted\n */\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\n accrueInterest();\n _reduceReservesFresh(reduceAmount);\n }\n\n /**\n * @notice The sender adds to reserves.\n * @param addAmount The amount of underlying token to add as reserves\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function addReserves(uint256 addAmount) external override nonReentrant {\n accrueInterest();\n _addReservesFresh(addAmount);\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:access Controlled by AccessControlManager\n */\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\n _checkAccessAllowed(\"setInterestRateModel(address)\");\n\n accrueInterest();\n _setInterestRateModelFresh(newInterestRateModel);\n }\n\n /**\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\n * \"forgiving\" the borrower. Healing is a situation that should rarely happen. However, some pools\n * may list risky assets or be configured improperly – we want to still handle such cases gracefully.\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\n * @dev This function does not call any Comptroller hooks (like \"healAllowed\"), because we assume\n * the Comptroller does all the necessary checks before calling this function.\n * @param payer account who repays the debt\n * @param borrower account to heal\n * @param repayAmount amount to repay\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\n * @custom:access Only Comptroller\n */\n function healBorrow(\n address payer,\n address borrower,\n uint256 repayAmount\n ) external override nonReentrant {\n if (repayAmount != 0) {\n comptroller.preRepayHook(address(this), borrower);\n }\n\n if (msg.sender != address(comptroller)) {\n revert HealBorrowUnauthorized();\n }\n\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n uint256 totalBorrowsNew = totalBorrows;\n\n uint256 actualRepayAmount;\n if (repayAmount != 0) {\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\n actualRepayAmount = _doTransferIn(payer, repayAmount);\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\n emit RepayBorrow(\n payer,\n borrower,\n actualRepayAmount,\n accountBorrowsPrev - actualRepayAmount,\n totalBorrowsNew\n );\n }\n\n // The transaction will fail if trying to repay too much\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\n if (badDebtDelta != 0) {\n uint256 badDebtOld = badDebt;\n uint256 badDebtNew = badDebtOld + badDebtDelta;\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\n badDebt = badDebtNew;\n\n // We treat healing as \"repayment\", where vToken is the payer\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\n }\n\n accountBorrows[borrower].principal = 0;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n emit HealBorrow(payer, borrower, repayAmount);\n }\n\n /**\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\n * the close factor check. The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\n * @custom:access Only Comptroller\n */\n function forceLiquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) external override {\n if (msg.sender != address(comptroller)) {\n revert ForceLiquidateBorrowUnauthorized();\n }\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\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 * @custom:event Emits Transfer, ReservesAdded events\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:access Not restricted\n */\n function seize(\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external override nonReentrant {\n _seize(msg.sender, liquidator, borrower, seizeTokens);\n }\n\n /**\n * @notice Updates bad debt\n * @dev Called only when bad debt is recovered from auction\n * @param recoveredAmount_ The amount of bad debt recovered\n * @custom:event Emits BadDebtRecovered event\n * @custom:access Only Shortfall contract\n */\n function badDebtRecovered(uint256 recoveredAmount_) external {\n require(msg.sender == shortfall, \"only shortfall contract can update bad debt\");\n require(recoveredAmount_ <= badDebt, \"more than bad debt recovered from auction\");\n\n uint256 badDebtOld = badDebt;\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\n badDebt = badDebtNew;\n\n emit BadDebtRecovered(badDebtOld, badDebtNew);\n }\n\n /**\n * @notice Sets protocol share reserve contract address\n * @param protocolShareReserve_ The address of the protocol share reserve contract\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\n * @custom:access Only Governance\n */\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\n _setProtocolShareReserve(protocolShareReserve_);\n }\n\n /**\n * @notice Sets shortfall contract address\n * @param shortfall_ The address of the shortfall contract\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n * @custom:access Only Governance\n */\n function setShortfallContract(address shortfall_) external onlyOwner {\n _setShortfallContract(shortfall_);\n }\n\n /**\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\n * @param token The address of the ERC-20 token to sweep\n * @custom:access Only Governance\n */\n function sweepToken(IERC20Upgradeable token) external override {\n require(msg.sender == owner(), \"VToken::sweepToken: only admin can sweep tokens\");\n require(address(token) != underlying, \"VToken::sweepToken: can not sweep underlying token\");\n uint256 balance = token.balanceOf(address(this));\n token.safeTransfer(owner(), balance);\n\n emit SweepToken(address(token));\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\n */\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return vTokenBalance User's balance of vTokens\n * @return borrowBalance Amount owed in terms of underlying\n * @return exchangeRate Stored exchange rate\n */\n function getAccountSnapshot(address account)\n external\n view\n override\n returns (\n uint256 error,\n uint256 vTokenBalance,\n uint256 borrowBalance,\n uint256 exchangeRate\n )\n {\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return cash The quantity of underlying asset owned by this contract\n */\n function getCash() external view override returns (uint256) {\n return _getCashPrior();\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return rate The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view override returns (uint256) {\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this v\n * @return rate The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view override returns (uint256) {\n return\n interestRateModel.getSupplyRate(\n _getCashPrior(),\n totalBorrows,\n totalReserves,\n reserveFactorMantissa,\n badDebt\n );\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 borrowBalance The calculated balance\n */\n function borrowBalanceStored(address account) external view override returns (uint256) {\n return _borrowBalanceStored(account);\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 exchangeRate Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() external view override returns (uint256) {\n return _exchangeRateStored();\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return exchangeRate Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\n accrueInterest();\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.\n * @return Always NO_ERROR\n * @custom:event Emits AccrueInterest event on success\n * @custom:access Not restricted\n */\n function accrueInterest() public virtual override returns (uint256) {\n /* Remember the initial block number */\n uint256 currentBlockNumber = _getBlockNumber();\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\n\n /* Short-circuit accumulating 0 interest */\n if (accrualBlockNumberPrior == currentBlockNumber) {\n return NO_ERROR;\n }\n\n /* Read the previous values out of storage */\n uint256 cashPrior = _getCashPrior();\n uint256 borrowsPrior = totalBorrows;\n uint256 reservesPrior = totalReserves;\n uint256 borrowIndexPrior = borrowIndex;\n\n /* Calculate the current borrow interest rate */\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \"borrow rate is absurdly high\");\n\n /* Calculate the number of blocks elapsed since the last accrual */\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\n Exp({ mantissa: reserveFactorMantissa }),\n interestAccumulated,\n reservesPrior\n );\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\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 NO_ERROR;\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 payer The address of the account which is sending the assets for supply\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 */\n function _mintFresh(\n address payer,\n address minter,\n uint256 mintAmount\n ) internal {\n /* Fail if mint not allowed */\n comptroller.preMintHook(address(this), minter, mintAmount);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert MintFreshnessCheck();\n }\n\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\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 * And write them into storage\n */\n totalSupply = totalSupply + mintTokens;\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\n accountTokens[minter] = balanceAfter;\n\n /* We emit a Mint event, and a Transfer event */\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\n emit Transfer(address(0), minter, mintTokens);\n }\n\n /**\n * @notice User redeems vTokens in exchange for the underlying asset\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 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 */\n function _redeemFresh(\n address redeemer,\n uint256 redeemTokensIn,\n uint256 redeemAmountIn\n ) internal {\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \"one of redeemTokensIn or redeemAmountIn must be zero\");\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert RedeemFreshnessCheck();\n }\n\n /* exchangeRate = invoke Exchange Rate Stored() */\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\n\n uint256 redeemTokens;\n uint256 redeemAmount;\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 */\n redeemTokens = redeemTokensIn;\n } else {\n /*\n * We get the current exchange rate and calculate the amount to be redeemed:\n * redeemTokens = redeemAmountIn / exchangeRate\n */\n redeemTokens = div_(redeemAmountIn, exchangeRate);\n\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\n }\n\n // redeemAmount = exchangeRate * redeemTokens\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\n\n // Revert if amount is zero\n if (redeemAmount == 0) {\n revert(\"redeemAmount is zero\");\n }\n\n /* Fail if redeem not allowed */\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\n\n /* Fail gracefully if protocol has insufficient cash */\n if (_getCashPrior() - totalReserves < redeemAmount) {\n revert RedeemTransferOutNotPossible();\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We write the previously calculated values into storage.\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\n */\n totalSupply = totalSupply - redeemTokens;\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\n accountTokens[redeemer] = balanceAfter;\n\n /*\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\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 _doTransferOut(redeemer, redeemAmount);\n\n /* We emit a Transfer event, and a Redeem event */\n emit Transfer(redeemer, address(this), redeemTokens);\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\n }\n\n /**\n * @notice Users borrow assets from the protocol to their own address\n * @param borrower User who borrows the assets\n * @param borrowAmount The amount of the underlying asset to borrow\n */\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\n /* Fail if borrow not allowed */\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert BorrowFreshnessCheck();\n }\n\n /* Fail gracefully if protocol has insufficient underlying cash */\n if (_getCashPrior() - totalReserves < borrowAmount) {\n revert BorrowCashNotAvailable();\n }\n\n /*\n * We calculate the new borrower and total borrow balances, failing on overflow:\n * accountBorrowNew = accountBorrow + borrowAmount\n * totalBorrowsNew = totalBorrows + borrowAmount\n */\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We write the previously calculated values into storage.\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\n `*/\n accountBorrows[borrower].principal = accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n /*\n * We invoke _doTransferOut for the borrower and the borrowAmount.\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(borrower, borrowAmount);\n\n /* We emit a Borrow event */\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\n * @return (uint) the actual repayment amount.\n */\n function _repayBorrowFresh(\n address payer,\n address borrower,\n uint256 repayAmount\n ) internal returns (uint256) {\n /* Fail if repayBorrow not allowed */\n comptroller.preRepayHook(address(this), borrower);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert RepayBorrowFreshnessCheck();\n }\n\n /* We fetch the amount the borrower owes, with accumulated interest */\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\n\n /* We write the previously calculated values into storage */\n accountBorrows[borrower].principal = accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n /* We emit a RepayBorrow event */\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\n\n return actualRepayAmount;\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n */\n function _liquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) internal nonReentrant {\n accrueInterest();\n\n uint256 error = vTokenCollateral.accrueInterest();\n if (error != NO_ERROR) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n revert LiquidateAccrueCollateralInterestFailed(error);\n }\n\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\n }\n\n /**\n * @notice The liquidator liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n */\n function _liquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) internal {\n /* Fail if liquidate not allowed */\n comptroller.preLiquidateHook(\n address(this),\n address(vTokenCollateral),\n borrower,\n repayAmount,\n skipLiquidityCheck\n );\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert LiquidateFreshnessCheck();\n }\n\n /* Verify vTokenCollateral market's block number equals current block number */\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\n revert LiquidateCollateralFreshnessCheck();\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n revert LiquidateLiquidatorIsBorrower();\n }\n\n /* Fail if repayAmount = 0 */\n if (repayAmount == 0) {\n revert LiquidateCloseAmountIsZero();\n }\n\n /* Fail if repayAmount = type(uint256).max */\n if (repayAmount == type(uint256).max) {\n revert LiquidateCloseAmountIsUintMax();\n }\n\n /* Fail if repayBorrow fails */\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\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.liquidateCalculateSeizeTokens(\n address(this),\n address(vTokenCollateral),\n actualRepayAmount\n );\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\n if (address(vTokenCollateral) == address(this)) {\n _seize(address(this), liquidator, borrower, seizeTokens);\n } else {\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\n }\n\n /* We emit a LiquidateBorrow event */\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\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 */\n function _seize(\n address seizerContract,\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) internal {\n /* Fail if seize not allowed */\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n revert LiquidateSeizeLiquidatorIsBorrower();\n }\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\n .liquidationIncentiveMantissa();\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the calculated values into storage */\n totalReserves = totalReservesNew;\n totalSupply = totalSupply - protocolSeizeTokens;\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\n\n /* Emit a Transfer event */\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\n emit Transfer(borrower, address(this), protocolSeizeTokens);\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\n }\n\n function _setComptroller(ComptrollerInterface newComptroller) internal {\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\n /**\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\n * @dev Admin function to set a new reserve factor\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\n */\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\n // Verify market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert SetReserveFactorFreshCheck();\n }\n\n // Check newReserveFactor ≤ maxReserveFactor\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\n revert SetReserveFactorBoundsCheck();\n }\n\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\n reserveFactorMantissa = newReserveFactorMantissa;\n\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\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 actualAddAmount The actual amount added, excluding the potential token fees\n */\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\n // totalReserves + actualAddAmount\n uint256 totalReservesNew;\n uint256 actualAddAmount;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert AddReservesFactorFreshCheck(actualAddAmount);\n }\n\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\n totalReservesNew = totalReserves + actualAddAmount;\n totalReserves = totalReservesNew;\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\n\n return actualAddAmount;\n }\n\n /**\n * @notice Reduces reserves by transferring to the protocol reserve contract\n * @dev Requires fresh interest accrual\n * @param reduceAmount Amount of reduction to reserves\n */\n function _reduceReservesFresh(uint256 reduceAmount) internal {\n // totalReserves - reduceAmount\n uint256 totalReservesNew;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert ReduceReservesFreshCheck();\n }\n\n // Fail gracefully if protocol has insufficient underlying cash\n if (_getCashPrior() < reduceAmount) {\n revert ReduceReservesCashNotAvailable();\n }\n\n // Check reduceAmount ≤ reserves[n] (totalReserves)\n if (reduceAmount > totalReserves) {\n revert ReduceReservesCashValidation();\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\n _doTransferOut(protocolShareReserve, reduceAmount);\n\n // Update the pool asset's state in the protocol share reserve for the above transfer.\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\n\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\n }\n\n /**\n * @notice updates the interest rate model (*requires fresh interest accrual)\n * @dev Admin function to update the interest rate model\n * @param newInterestRateModel the new interest rate model to use\n */\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\n // Used to store old model for use in the event that is emitted on success\n InterestRateModel oldInterestRateModel;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert SetInterestRateModelFreshCheck();\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\n /*** Safe Token ***/\n\n /**\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\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 * @param from Sender of the underlying tokens\n * @param amount Amount of underlying to transfer\n * @return Actual amount received\n */\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n uint256 balanceBefore = token.balanceOf(address(this));\n token.safeTransferFrom(from, address(this), amount);\n uint256 balanceAfter = token.balanceOf(address(this));\n // Return the amount that was *actually* transferred\n return balanceAfter - balanceBefore;\n }\n\n /**\n * @dev Just a regular ERC-20 transfer, reverts on failure\n * @param to Receiver of the underlying tokens\n * @param amount Amount of underlying to transfer\n */\n function _doTransferOut(address to, uint256 amount) internal virtual {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n token.safeTransfer(to, amount);\n }\n\n /**\n * @notice Transfer `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 */\n function _transferTokens(\n address spender,\n address src,\n address dst,\n uint256 tokens\n ) internal {\n /* Fail if transfer not allowed */\n comptroller.preTransferHook(address(this), src, dst, tokens);\n\n /* Do not allow self-transfers */\n if (src == dst) {\n revert TransferNotAllowed();\n }\n\n /* Get the allowance, infinite for the account owner */\n uint256 startingAllowance;\n if (spender == src) {\n startingAllowance = type(uint256).max;\n } else {\n startingAllowance = transferAllowances[src][spender];\n }\n\n /* Do the calculations, checking for {under,over}flow */\n uint256 allowanceNew = startingAllowance - tokens;\n uint256 srcTokensNew = accountTokens[src] - tokens;\n uint256 dstTokensNew = accountTokens[dst] + tokens;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n\n accountTokens[src] = srcTokensNew;\n accountTokens[dst] = dstTokensNew;\n\n /* Eat some of the allowance (if necessary) */\n if (startingAllowance != type(uint256).max) {\n transferAllowances[src][spender] = allowanceNew;\n }\n\n /* We emit a Transfer event */\n emit Transfer(src, dst, tokens);\n }\n\n /**\n * @notice Initialize the 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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param accessControlManager_ AccessControlManager contract address\n * @param riskManagement Addresses of risk & income related contracts\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\n */\n function _initialize(\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 admin_,\n address accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) internal onlyInitializing {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\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 _setComptroller(comptroller_);\n\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\n accrualBlockNumber = _getBlockNumber();\n borrowIndex = MANTISSA_ONE;\n\n // Set the interest rate model (depends on block number / borrow index)\n _setInterestRateModelFresh(interestRateModel_);\n\n _setReserveFactorFresh(reserveFactorMantissa_);\n\n name = name_;\n symbol = symbol_;\n decimals = decimals_;\n _setShortfallContract(riskManagement.shortfall);\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\n\n // Set underlying and sanity check it\n underlying = underlying_;\n IERC20Upgradeable(underlying).totalSupply();\n\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\n _notEntered = true;\n _transferOwnership(admin_);\n }\n\n function _setShortfallContract(address shortfall_) internal {\n ensureNonzeroAddress(shortfall_);\n address oldShortfall = shortfall;\n shortfall = shortfall_;\n emit NewShortfallContract(oldShortfall, shortfall_);\n }\n\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\n ensureNonzeroAddress(protocolShareReserve_);\n address oldProtocolShareReserve = address(protocolShareReserve);\n protocolShareReserve = protocolShareReserve_;\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\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 virtual returns (uint256) {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n return token.balanceOf(address(this));\n }\n\n /**\n * @dev Function to simply retrieve block number\n * This exists mainly for inheriting test contracts to stub this result.\n * @return Current block number\n */\n function _getBlockNumber() internal view virtual returns (uint256) {\n return block.number;\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 borrowBalance the calculated balance\n */\n function _borrowBalanceStored(address account) internal view returns (uint256) {\n /* Get borrowBalance and borrowIndex */\n BorrowSnapshot memory 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 0;\n }\n\n /* Calculate new borrow balance using the interest index:\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\n */\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\n\n return principalTimesIndex / borrowSnapshot.interestIndex;\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 exchangeRate Calculated exchange rate scaled by 1e18\n */\n function _exchangeRateStored() internal view virtual returns (uint256) {\n uint256 _totalSupply = totalSupply;\n if (_totalSupply == 0) {\n /*\n * If there are no tokens minted:\n * exchangeRate = initialExchangeRate\n */\n return initialExchangeRateMantissa;\n }\n /*\n * Otherwise:\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\n */\n uint256 totalCash = _getCashPrior();\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\n\n return exchangeRate;\n }\n}\n" + }, + "contracts/VTokenInterfaces.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { ComptrollerInterface } from \"./ComptrollerInterface.sol\";\nimport { InterestRateModel } from \"./InterestRateModel.sol\";\n\n/**\n * @title VTokenStorage\n * @author Venus\n * @notice Storage layout used by the `VToken` contract\n */\n// solhint-disable-next-line max-states-count\ncontract VTokenStorage {\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 uint256 principal;\n uint256 interestIndex;\n }\n\n /**\n * @dev Guard variable for re-entrancy checks\n */\n bool internal _notEntered;\n\n /**\n * @notice Underlying asset for this VToken\n */\n address public underlying;\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 Protocol share Reserve contract address\n */\n address payable public protocolShareReserve;\n\n // Maximum borrow rate that can ever be applied (.0005% / block)\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\n\n // Maximum fraction of interest that can be set aside for reserves\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\n uint256 internal initialExchangeRateMantissa;\n\n /**\n * @notice Fraction of interest currently set aside for reserves\n */\n uint256 public reserveFactorMantissa;\n\n /**\n * @notice Block number that interest was last accrued at\n */\n uint256 public accrualBlockNumber;\n\n /**\n * @notice Accumulator of the total earned interest rate since the opening of the market\n */\n uint256 public borrowIndex;\n\n /**\n * @notice Total amount of outstanding borrows of the underlying in this market\n */\n uint256 public totalBorrows;\n\n /**\n * @notice Total amount of reserves of the underlying held in this market\n */\n uint256 public totalReserves;\n\n /**\n * @notice Total number of tokens in circulation\n */\n uint256 public totalSupply;\n\n /**\n * @notice Total bad debt of the market\n */\n uint256 public badDebt;\n\n // Official record of token balances for each account\n mapping(address => uint256) internal accountTokens;\n\n // Approved token transfer amounts on behalf of others\n mapping(address => mapping(address => uint256)) internal transferAllowances;\n\n // Mapping of account addresses to outstanding borrow balances\n mapping(address => BorrowSnapshot) internal accountBorrows;\n\n /**\n * @notice Share of seized collateral that is added to reserves\n */\n uint256 public protocolSeizeShareMantissa;\n\n /**\n * @notice Storage of Shortfall contract address\n */\n address public shortfall;\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[50] private __gap;\n}\n\n/**\n * @title VTokenInterface\n * @author Venus\n * @notice Interface implemented by the `VToken` contract\n */\nabstract contract VTokenInterface is VTokenStorage {\n struct RiskManagementInit {\n address shortfall;\n address payable protocolShareReserve;\n }\n\n /*** Market Events ***/\n\n /**\n * @notice Event emitted when interest is accrued\n */\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\n\n /**\n * @notice Event emitted when tokens are minted\n */\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\n\n /**\n * @notice Event emitted when tokens are redeemed\n */\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\n\n /**\n * @notice Event emitted when underlying is borrowed\n */\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\n\n /**\n * @notice Event emitted when a borrow is repaid\n */\n event RepayBorrow(\n address indexed payer,\n address indexed borrower,\n uint256 repayAmount,\n uint256 accountBorrows,\n uint256 totalBorrows\n );\n\n /**\n * @notice Event emitted when bad debt is accumulated on a market\n * @param borrower borrower to \"forgive\"\n * @param badDebtDelta amount of new bad debt recorded\n * @param badDebtOld previous bad debt value\n * @param badDebtNew new bad debt value\n */\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\n\n /**\n * @notice Event emitted when bad debt is recovered via an auction\n * @param badDebtOld previous bad debt value\n * @param badDebtNew new bad debt value\n */\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\n\n /**\n * @notice Event emitted when a borrow is liquidated\n */\n event LiquidateBorrow(\n address indexed liquidator,\n address indexed borrower,\n uint256 repayAmount,\n address indexed vTokenCollateral,\n uint256 seizeTokens\n );\n\n /*** Admin Events ***/\n\n /**\n * @notice Event emitted when comptroller is changed\n */\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\n\n /**\n * @notice Event emitted when shortfall contract address is changed\n */\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\n\n /**\n * @notice Event emitted when protocol share reserve contract address is changed\n */\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\n\n /**\n * @notice Event emitted when interestRateModel is changed\n */\n event NewMarketInterestRateModel(\n InterestRateModel indexed oldInterestRateModel,\n InterestRateModel indexed newInterestRateModel\n );\n\n /**\n * @notice Event emitted when protocol seize share is changed\n */\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\n\n /**\n * @notice Event emitted when the reserve factor is changed\n */\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\n\n /**\n * @notice Event emitted when the reserves are added\n */\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\n\n /**\n * @notice Event emitted when the reserves are reduced\n */\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\n\n /**\n * @notice EIP20 Transfer event\n */\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /**\n * @notice EIP20 Approval event\n */\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Event emitted when healing the borrow\n */\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\n\n /**\n * @notice Event emitted when tokens are swept\n */\n event SweepToken(address indexed token);\n\n /*** User Interface ***/\n\n function mint(uint256 mintAmount) external virtual returns (uint256);\n\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\n\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\n\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\n\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\n\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\n\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\n\n function liquidateBorrow(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external virtual returns (uint256);\n\n function healBorrow(\n address payer,\n address borrower,\n uint256 repayAmount\n ) external virtual;\n\n function forceLiquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipCloseFactorCheck\n ) external virtual;\n\n function seize(\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external virtual;\n\n function transfer(address dst, uint256 amount) external virtual returns (bool);\n\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) external virtual returns (bool);\n\n function accrueInterest() external virtual returns (uint256);\n\n function sweepToken(IERC20Upgradeable token) external virtual;\n\n /*** Admin Functions ***/\n\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\n\n function reduceReserves(uint256 reduceAmount) external virtual;\n\n function exchangeRateCurrent() external virtual returns (uint256);\n\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\n\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\n\n function addReserves(uint256 addAmount) external virtual;\n\n function totalBorrowsCurrent() external virtual returns (uint256);\n\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\n\n function approve(address spender, uint256 amount) external virtual returns (bool);\n\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\n\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\n\n function allowance(address owner, address spender) external view virtual returns (uint256);\n\n function balanceOf(address owner) external view virtual returns (uint256);\n\n function getAccountSnapshot(address account)\n external\n view\n virtual\n returns (\n uint256,\n uint256,\n uint256,\n uint256\n );\n\n function borrowRatePerBlock() external view virtual returns (uint256);\n\n function supplyRatePerBlock() external view virtual returns (uint256);\n\n function borrowBalanceStored(address account) external view virtual returns (uint256);\n\n function exchangeRateStored() external view virtual returns (uint256);\n\n function getCash() external view virtual returns (uint256);\n\n /**\n * @notice Indicator that this is a VToken contract (for inspection)\n * @return Always true\n */\n function isVToken() external pure virtual returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/WhitePaperInterestRateModel.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { InterestRateModel } from \"./InterestRateModel.sol\";\nimport { BLOCKS_PER_YEAR, EXP_SCALE, MANTISSA_ONE } from \"./lib/constants.sol\";\n\n/**\n * @title Compound's WhitePaperInterestRateModel Contract\n * @author Compound\n * @notice The parameterized model described in section 2.4 of the original Compound Protocol whitepaper\n */\ncontract WhitePaperInterestRateModel is InterestRateModel {\n /**\n * @notice The multiplier of utilization rate that gives the slope of the interest rate\n */\n uint256 public immutable multiplierPerBlock;\n\n /**\n * @notice The base interest rate which is the y-intercept when utilization rate is 0\n */\n uint256 public immutable baseRatePerBlock;\n\n event NewInterestParams(uint256 baseRatePerBlock, uint256 multiplierPerBlock);\n\n /**\n * @notice Construct an interest rate model\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by EXP_SCALE)\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)\n */\n constructor(uint256 baseRatePerYear, uint256 multiplierPerYear) {\n baseRatePerBlock = baseRatePerYear / BLOCKS_PER_YEAR;\n multiplierPerBlock = multiplierPerYear / BLOCKS_PER_YEAR;\n\n emit NewInterestParams(baseRatePerBlock, multiplierPerBlock);\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 * @param badDebt The amount of badDebt in the market\n * @return The borrow rate percentage per block as a mantissa (scaled by EXP_SCALE)\n */\n function getBorrowRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) public view override returns (uint256) {\n uint256 ur = utilizationRate(cash, borrows, reserves, badDebt);\n return ((ur * multiplierPerBlock) / EXP_SCALE) + 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 * @param badDebt The amount of badDebt in the market\n * @return The supply rate percentage per block as a mantissa (scaled by EXP_SCALE)\n */\n function getSupplyRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 reserveFactorMantissa,\n uint256 badDebt\n ) public view override returns (uint256) {\n uint256 oneMinusReserveFactor = MANTISSA_ONE - reserveFactorMantissa;\n uint256 borrowRate = getBorrowRate(cash, borrows, reserves, badDebt);\n uint256 rateToPool = (borrowRate * oneMinusReserveFactor) / EXP_SCALE;\n uint256 incomeToDistribute = borrows * rateToPool;\n uint256 supply = cash + borrows + badDebt - reserves;\n return incomeToDistribute / supply;\n }\n\n /**\n * @notice Calculates the utilization rate of the market: `(borrows + badDebt) / (cash + borrows + badDebt - 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 * @param badDebt The amount of badDebt in the market\n * @return The utilization rate as a mantissa between [0, MANTISSA_ONE]\n */\n function utilizationRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) public pure returns (uint256) {\n // Utilization rate is 0 when there are no borrows and badDebt\n if ((borrows + badDebt) == 0) {\n return 0;\n }\n\n uint256 rate = ((borrows + badDebt) * EXP_SCALE) / (cash + borrows + badDebt - reserves);\n\n if (rate > EXP_SCALE) {\n rate = EXP_SCALE;\n }\n\n return rate;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "yul": true + } + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index 8cfcbeb96..c8b37000a 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -719,6 +719,12 @@ export const globalConfig: NetworkConfig = { supplySpeeds: ["1860119047619047"], // 1500 HAY over 28 days (806400 blocks) borrowSpeeds: ["1860119047619047"], // 1500 HAY over 28 days (806400 blocks) }, + { + asset: "HAY", + markets: ["HAY"], + supplySpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) + borrowSpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) + }, ], }, { @@ -1410,6 +1416,12 @@ export const globalConfig: NetworkConfig = { supplySpeeds: ["1860119047619047"], // 1500 HAY over 28 days (806400 blocks) borrowSpeeds: ["1860119047619047"], // 1500 HAY over 28 days (806400 blocks) }, + { + asset: "HAY", + markets: ["HAY"], + supplySpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) + borrowSpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) + }, ], }, { From b5b1558ef375adde0892343e4caed0ad18b6a045 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Wed, 23 Aug 2023 13:30:21 +0100 Subject: [PATCH 07/39] fix: include reward token in event --- contracts/Comptroller.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index 5a61268fd..89b1632cf 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -86,7 +86,7 @@ contract Comptroller is event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap); /// @notice Emitted when a rewards distributor is added - event NewRewardsDistributor(address indexed rewardsDistributor); + event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken); /// @notice Emitted when a market is supported event MarketSupported(VToken vToken); @@ -977,7 +977,7 @@ contract Comptroller is _rewardsDistributor.initializeMarket(address(allMarkets[i])); } - emit NewRewardsDistributor(address(_rewardsDistributor)); + emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken())); } /** From 83c1c3b5a52c383241373dce676bab4c3b9e3fb5 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Wed, 23 Aug 2023 18:01:16 +0100 Subject: [PATCH 08/39] fix: fixed tests --- tests/hardhat/Rewards.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/hardhat/Rewards.ts b/tests/hardhat/Rewards.ts index a2a55118a..bf4e9b218 100644 --- a/tests/hardhat/Rewards.ts +++ b/tests/hardhat/Rewards.ts @@ -256,7 +256,7 @@ describe("Rewards: Tests", async function () { await expect(comptrollerProxy.addRewardsDistributor(rewardsDistributor.address)) .to.emit(comptrollerProxy, "NewRewardsDistributor") - .withArgs(rewardsDistributor.address); + .withArgs(rewardsDistributor.address, xvs.address); }); it("Emits event correctly", async () => { @@ -270,7 +270,7 @@ describe("Rewards: Tests", async function () { await expect(comptrollerProxy.addRewardsDistributor(rewardsDistributor.address)) .to.emit(comptrollerProxy, "NewRewardsDistributor") - .withArgs(rewardsDistributor.address); + .withArgs(rewardsDistributor.address, mockWBTC.address); }); it("Claim XVS", async () => { From bab199d1c26965c717eca987ab5184b0ba4ec9c3 Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Thu, 24 Aug 2023 12:50:37 +0000 Subject: [PATCH 09/39] chore(release): 2.0.0-dev.6 [skip ci] ## [2.0.0-dev.6](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.5...v2.0.0-dev.6) (2023-08-24) ### Bug Fixes * fixed tests ([83c1c3b](https://github.com/VenusProtocol/isolated-pools/commit/83c1c3b5a52c383241373dce676bab4c3b9e3fb5)) * include reward token in event ([b5b1558](https://github.com/VenusProtocol/isolated-pools/commit/b5b1558ef375adde0892343e4caed0ad18b6a045)) --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67b4b909c..10d2282dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [2.0.0-dev.6](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.5...v2.0.0-dev.6) (2023-08-24) + + +### Bug Fixes + +* fixed tests ([83c1c3b](https://github.com/VenusProtocol/isolated-pools/commit/83c1c3b5a52c383241373dce676bab4c3b9e3fb5)) +* include reward token in event ([b5b1558](https://github.com/VenusProtocol/isolated-pools/commit/b5b1558ef375adde0892343e4caed0ad18b6a045)) + ## [2.0.0-dev.5](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.4...v2.0.0-dev.5) (2023-08-18) diff --git a/package.json b/package.json index 8dcad45c4..1e1bb424c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "2.0.0-dev.5", + "version": "2.0.0-dev.6", "description": "", "files": [ "artifacts", From 3bd2009ddd8577b015263bf082685fa6be113e43 Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Thu, 24 Aug 2023 15:57:39 +0200 Subject: [PATCH 10/39] docs: fix CVP-02 --- contracts/Comptroller.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index 89b1632cf..9d2de5830 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -956,7 +956,8 @@ contract Comptroller is } /** - * @notice Add a new RewardsDistributor and initialize it with all markets + * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor + * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block * @dev Only callable by the admin * @param _rewardsDistributor Address of the RewardDistributor contract to add * @custom:access Only Governance From 814fc59cbda5eb912d0d83305fe1253b6c353756 Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Thu, 24 Aug 2023 14:28:29 +0000 Subject: [PATCH 11/39] chore(release): 2.0.0-dev.7 [skip ci] ## [2.0.0-dev.7](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.6...v2.0.0-dev.7) (2023-08-24) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10d2282dc..66114bbcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [2.0.0-dev.7](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.6...v2.0.0-dev.7) (2023-08-24) + ## [2.0.0-dev.6](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.5...v2.0.0-dev.6) (2023-08-24) diff --git a/package.json b/package.json index 1e1bb424c..f3af08f4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "2.0.0-dev.6", + "version": "2.0.0-dev.7", "description": "", "files": [ "artifacts", From ed4ed8a3a26620d06143cf9912889cb82bb35cd9 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Fri, 25 Aug 2023 12:59:03 +0100 Subject: [PATCH 12/39] fix: added SD rewards distributor --- helpers/deploymentConfig.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index c8b37000a..d5f4828ab 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -725,6 +725,12 @@ export const globalConfig: NetworkConfig = { supplySpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) borrowSpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) }, + { + asset: "SD", + markets: ["SD"], + supplySpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + borrowSpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + }, ], }, { @@ -1422,6 +1428,12 @@ export const globalConfig: NetworkConfig = { supplySpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) borrowSpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) }, + { + asset: "SD", + markets: ["SD"], + supplySpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + borrowSpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + }, ], }, { From 50d6edd8e6184407777eeb8fc281fe3862a7988c Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Fri, 25 Aug 2023 15:12:59 +0100 Subject: [PATCH 13/39] fix: fix deployment of comptroller and verification --- deployments/bscmainnet/ComptrollerImpl.json | 2 +- hardhat.config.ts | 32 +++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/deployments/bscmainnet/ComptrollerImpl.json b/deployments/bscmainnet/ComptrollerImpl.json index caf9d4cfe..318c9e64d 100644 --- a/deployments/bscmainnet/ComptrollerImpl.json +++ b/deployments/bscmainnet/ComptrollerImpl.json @@ -1,5 +1,5 @@ { - "address": "0x939C05e2E694db68cE54d80bf29926b09190aA0F", + "address": "0x7b58D42f0051F838057ca5dF23B46f6FfdabdA85", "abi": [ { "inputs": [ diff --git a/hardhat.config.ts b/hardhat.config.ts index 50045891f..39e9a9548 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -15,6 +15,7 @@ import "solidity-coverage"; import "solidity-docgen"; import { convertToUnit } from "./helpers/utils"; +import { run } from "hardhat"; dotenv.config(); @@ -72,16 +73,23 @@ task("addMarket", "Add a market to an existing pool") task("deployComptroller", "Deploys a Comptroller Implementation") .addParam("contractName", "Contract name, later we can load contracts by name") .addParam("poolRegistry", "Address of PoolRegistry Contract") - .addParam("accessControl", "Address of AccessControlManager contract") + .addParam("verify", "Verify the contract") .setAction(async (taskArgs, hre) => { const { deployer } = await hre.getNamedAccounts(); const Comptroller: DeployResult = await hre.deployments.deploy(taskArgs.contractName, { contract: "Comptroller", from: deployer, - args: [taskArgs.poolRegistry, taskArgs.accessControl], + args: [taskArgs.poolRegistry], log: true, }); + if (taskArgs.verify == "true") { + await hre.run("verify:verify", { + address: Comptroller.address, + constructorArguments: [taskArgs.poolRegistry], + }); + } + console.log("Comptroller implementation deployed with address: " + Comptroller.address); }); @@ -167,6 +175,14 @@ const config: HardhatUserConfig = { mnemonic: process.env.MNEMONIC || "", }, }, + bscmainnet: { + url: "https://bsc-dataseed.binance.org/", + chainId: 56, + live: true, + accounts: { + mnemonic: process.env.MNEMONIC || "", + }, + }, }, gasReporter: { enabled: process.env.REPORT_GAS !== undefined, @@ -182,7 +198,19 @@ const config: HardhatUserConfig = { browserURL: "https://testnet.bscscan.com", }, }, + { + network: "bscmainnet", + chainId: 56, + urls: { + apiURL: "https://api.bscscan.com/api", + browserURL: "https://bscscan.com", + }, + }, ], + apiKey: { + bscmainnet: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", + testnet: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", + } }, paths: { tests: "./tests", From 3599ed40c6c10f1f09df2d7288566eccb7c6e2a2 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Fri, 25 Aug 2023 15:16:22 +0100 Subject: [PATCH 14/39] fix: deployed latest comptroller --- deployments/bscmainnet/ComptrollerImpl.json | 168 +++++++++++--------- 1 file changed, 89 insertions(+), 79 deletions(-) diff --git a/deployments/bscmainnet/ComptrollerImpl.json b/deployments/bscmainnet/ComptrollerImpl.json index 318c9e64d..57bc9b5d1 100644 --- a/deployments/bscmainnet/ComptrollerImpl.json +++ b/deployments/bscmainnet/ComptrollerImpl.json @@ -1,5 +1,5 @@ { - "address": "0x7b58D42f0051F838057ca5dF23B46f6FfdabdA85", + "address": "0x17a6ac4f7f01387303deB1D78f01aC0A0C1a75b0", "abi": [ { "inputs": [ @@ -546,6 +546,12 @@ "internalType": "address", "name": "rewardsDistributor", "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" } ], "name": "NewRewardsDistributor", @@ -1658,39 +1664,43 @@ "type": "function" } ], - "transactionHash": "0xe721740627229bfeb4611dcdf94c875119decdb218dc5dc2ce285013b42322e9", + "transactionHash": "0x404572cb1f8beb703369f9e8a142e4c7e97d1119d63b487ec6c8f09aa7e920ec", "receipt": { "to": null, - "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", - "contractAddress": "0x939C05e2E694db68cE54d80bf29926b09190aA0F", - "transactionIndex": 193, - "gasUsed": "4732821", - "logsBloom": "0x00000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000800000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x377fcacda01226ab3e5bbabcc5244f5589914673d059d4a86213cb0c9101f17e", - "transactionHash": "0xe721740627229bfeb4611dcdf94c875119decdb218dc5dc2ce285013b42322e9", + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x17a6ac4f7f01387303deB1D78f01aC0A0C1a75b0", + "transactionIndex": 143, + "gasUsed": "4697933", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7aeda808ef0049041c57e712e2cbb1212f5e5be92493692c9aa7d508ae47950a", + "transactionHash": "0x404572cb1f8beb703369f9e8a142e4c7e97d1119d63b487ec6c8f09aa7e920ec", "logs": [ { - "transactionIndex": 193, - "blockNumber": 29356749, - "transactionHash": "0xe721740627229bfeb4611dcdf94c875119decdb218dc5dc2ce285013b42322e9", - "address": "0x939C05e2E694db68cE54d80bf29926b09190aA0F", - "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "transactionIndex": 143, + "blockNumber": 31163370, + "transactionHash": "0x404572cb1f8beb703369f9e8a142e4c7e97d1119d63b487ec6c8f09aa7e920ec", + "address": "0x17a6ac4f7f01387303deB1D78f01aC0A0C1a75b0", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", - "logIndex": 368, - "blockHash": "0x377fcacda01226ab3e5bbabcc5244f5589914673d059d4a86213cb0c9101f17e" + "logIndex": 336, + "blockHash": "0x7aeda808ef0049041c57e712e2cbb1212f5e5be92493692c9aa7d508ae47950a" } ], - "blockNumber": 29356749, - "cumulativeGasUsed": "24547091", + "blockNumber": 31163370, + "cumulativeGasUsed": "18918722", "status": 1, "byzantium": true }, - "args": ["0x9F7b01A536aFA00EF10310A162877fd792cD0666"], + "args": [ + "0x9F7b01A536aFA00EF10310A162877fd792cD0666" + ], "numDeployments": 1, - "solcInputHash": "c8d07bff3d62f1243365b7988d183415", - "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"ActionPaused\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"cap\",\"type\":\"uint256\"}],\"name\":\"BorrowCapExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedLessThanOrEqualTo\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"CollateralExceedsThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ComptrollerMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"collateralToSeize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCollateral\",\"type\":\"uint256\"}],\"name\":\"InsufficientCollateral\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientShortfall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCollateralFactor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLiquidationThreshold\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"}],\"name\":\"MarketAlreadyListed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"MarketNotCollateral\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"}],\"name\":\"MarketNotListed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopsLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredLoops\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedGreaterThan\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"MinimalCollateralViolated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonzeroBorrowBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"PriceError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"SnapshotError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"cap\",\"type\":\"uint256\"}],\"name\":\"SupplyCapExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooMuchRepay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"calledContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"methodSignature\",\"type\":\"string\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"expectedSender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"actualSender\",\"type\":\"address\"}],\"name\":\"UnexpectedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"pauseState\",\"type\":\"bool\"}],\"name\":\"ActionPausedMarket\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketExited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketSupported\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMaxLoopsLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newmaxLoopsLimit\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBorrowCap\",\"type\":\"uint256\"}],\"name\":\"NewBorrowCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCloseFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCloseFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCollateralFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCollateralFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldLiquidationIncentiveMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"NewLiquidationIncentive\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldLiquidationThresholdMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLiquidationThresholdMantissa\",\"type\":\"uint256\"}],\"name\":\"NewLiquidationThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMinLiquidatableCollateral\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMinLiquidatableCollateral\",\"type\":\"uint256\"}],\"name\":\"NewMinLiquidatableCollateral\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"oldPriceOracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"newPriceOracle\",\"type\":\"address\"}],\"name\":\"NewPriceOracle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardsDistributor\",\"type\":\"address\"}],\"name\":\"NewRewardsDistributor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSupplyCap\",\"type\":\"uint256\"}],\"name\":\"NewSupplyCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract RewardsDistributor\",\"name\":\"_rewardsDistributor\",\"type\":\"address\"}],\"name\":\"addRewardsDistributor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"checkMembership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"vTokens\",\"type\":\"address[]\"}],\"name\":\"enterMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenAddress\",\"type\":\"address\"}],\"name\":\"exitMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllMarkets\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAssetsIn\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getBorrowingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenModify\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"getHypotheticalAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRewardDistributors\",\"outputs\":[{\"internalType\":\"contract RewardsDistributor[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"getRewardsByMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"supplySpeed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowSpeed\",\"type\":\"uint256\"}],\"internalType\":\"struct ComptrollerStorage.RewardSpeeds[]\",\"name\":\"rewardSpeeds\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"healAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accessControlManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isComptroller\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"isDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"isMarketListed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract VToken\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ComptrollerStorage.LiquidationOrder[]\",\"name\":\"orders\",\"type\":\"tuple[]\"}],\"name\":\"liquidateAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateCalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokensToSeize\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidationThresholdMantissa\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLoopsLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minLiquidatableCollateral\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"preBorrowHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"skipLiquidityCheck\",\"type\":\"bool\"}],\"name\":\"preLiquidateHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"mintAmount\",\"type\":\"uint256\"}],\"name\":\"preMintHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"preRedeemHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"}],\"name\":\"preRepayHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"seizerContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"}],\"name\":\"preSeizeHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"preTransferHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"marketsList\",\"type\":\"address[]\"},{\"internalType\":\"enum ComptrollerStorage.Action[]\",\"name\":\"actionsList\",\"type\":\"uint8[]\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"setActionsPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"setCloseFactor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLiquidationThresholdMantissa\",\"type\":\"uint256\"}],\"name\":\"setCollateralFactor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"setLiquidationIncentive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newBorrowCaps\",\"type\":\"uint256[]\"}],\"name\":\"setMarketBorrowCaps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newSupplyCaps\",\"type\":\"uint256[]\"}],\"name\":\"setMarketSupplyCaps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setMaxLoopsLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newMinLiquidatableCollateral\",\"type\":\"uint256\"}],\"name\":\"setMinLiquidatableCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"setPriceOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"supportMarket\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action to check\",\"market\":\"vToken address\"},\"returns\":{\"_0\":\"paused True if the action is paused otherwise false\"}},\"addRewardsDistributor(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewRewardsDistributor with distributor address\",\"details\":\"Only callable by the admin\",\"params\":{\"_rewardsDistributor\":\"Address of the RewardDistributor contract to add\"}},\"checkMembership(address,address)\":{\"params\":{\"account\":\"The address of the account to check\",\"vToken\":\"The vToken to check\"},\"returns\":{\"_0\":\"True if the account is in the market specified, otherwise false.\"}},\"constructor\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"params\":{\"poolRegistry_\":\"Pool registry address\"}},\"enterMarkets(address[])\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if entering any of the markets is pausedMarketNotListed error is thrown if any of the markets is not listed\",\"custom:event\":\"MarketEntered is emitted for each market on success\",\"params\":{\"vTokens\":\"The list of addresses of the vToken markets to be enabled\"},\"returns\":{\"_0\":\"errors An array of NO_ERROR for compatibility with Venus core tooling\"}},\"exitMarket(address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if exiting the market is pausedNonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if exiting the market would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"custom:event\":\"MarketExited is emitted on success\",\"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\"},\"returns\":{\"_0\":\"error Always NO_ERROR for compatibility with Venus core tooling\"}},\"getAccountLiquidity(address)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"params\":{\"account\":\"The account get liquidity for\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Account liquidity in excess of liquidation threshold requirements,\",\"shortfall\":\"Account shortfall below liquidation threshold requirements\"}},\"getAllMarkets()\":{\"details\":\"The automatic getter may be used to access an individual market.\",\"returns\":{\"_0\":\"markets The list of market addresses\"}},\"getAssetsIn(address)\":{\"params\":{\"account\":\"The address of the account to pull assets for\"},\"returns\":{\"_0\":\"A list with the assets the account has entered\"}},\"getBorrowingPower(address)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"params\":{\"account\":\"The account get liquidity for\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Account liquidity in excess of collateral requirements,\",\"shortfall\":\"Account shortfall below collateral requirements\"}},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"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\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Hypothetical account liquidity in excess of collateral requirements,\",\"shortfall\":\"Hypothetical account shortfall below collateral requirements\"}},\"getRewardDistributors()\":{\"returns\":{\"_0\":\"Array of RewardDistributor addresses\"}},\"getRewardsByMarket(address)\":{\"params\":{\"vToken\":\"The vToken to get the reward speeds for\"},\"returns\":{\"rewardSpeeds\":\"Array of total supply and borrow speeds and reward token for all reward distributors\"}},\"healAccount(address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"CollateralExceedsThreshold error is thrown when the collateral is too big for healingSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"user\":\"account to heal\"}},\"initialize(uint256,address)\":{\"params\":{\"accessControlManager\":\"Access control manager contract address\",\"loopLimit\":\"Limit for the loops can iterate to avoid the DOS\"}},\"isComptroller()\":{\"returns\":{\"_0\":\"Always true\"}},\"isDeprecated(address)\":{\"details\":\"All borrows in a deprecated vToken market can be immediately liquidated\",\"params\":{\"vToken\":\"The market to check if deprecated\"},\"returns\":{\"_0\":\"deprecated True if the given vToken market has been deprecated\"}},\"isMarketListed(address)\":{\"params\":{\"vToken\":\"vToken Address for the market to check\"},\"returns\":{\"_0\":\"listed True if listed otherwise false\"}},\"liquidateAccount(address,(address,address,uint256)[])\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidationInsufficientCollateral error is thrown when there is not enough collateral to cover the debtSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"borrower\":\"the borrower address\",\"orders\":\"an array of liquidation orders\"}},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"custom:error\":\"PriceError if the oracle returns an invalid price\",\"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\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"tokensToSeize\":\"Number of vTokenCollateral tokens to be seized in a liquidation\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"preLiquidateHook(address,address,address,uint256,bool)\":{\"custom:error\":\"ActionPaused error is thrown if liquidations are paused in this marketMarketNotListed error is thrown if either collateral or borrowed token is not listedTooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factorMinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidationsInsufficientShortfall is thrown when trying to liquidate a healthy accountSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"borrower\":\"The address of the borrower\",\"repayAmount\":\"The amount of underlying being repaid\",\"skipLiquidityCheck\":\"Allows the borrow to be liquidated regardless of the account liquidity\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"preMintHook(address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if supplying to this market is pausedMarketNotListed error is thrown when the market is not listedSupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\",\"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\"}},\"preRedeemHook(address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if withdrawals are paused in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"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\"}},\"preRepayHook(address,address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if repayments are paused in this marketMarketNotListed error is thrown when the market is not listed\",\"params\":{\"borrower\":\"The account which would borrowed the asset\",\"vToken\":\"The market to verify the repay against\"}},\"preSeizeHook(address,address,address,address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if seizing this type of collateral is pausedMarketNotListed error is thrown if either collateral or borrowed token is not listedComptrollerMismatch error is when seizer contract or seized asset belong to different pools\",\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizerContract\":\"Contract that tries to seize the asset (either borrowed vToken or Comptroller)\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"preTransferHook(address,address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if withdrawals are paused in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"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\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewAccessControlManager event\",\"details\":\"Admin function to set address of AccessControlManager\",\"params\":{\"accessControlManager_\":\"The new address of the AccessControlManager\"}},\"setActionsPaused(address[],uint8[],bool)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"actionsList\":\"List of action ids to pause/unpause\",\"marketsList\":\"Markets to pause/unpause the actions on\",\"paused\":\"The new paused state (true=paused, false=unpaused)\"}},\"setCloseFactor(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:event\":\"Emits NewCloseFactor on success\",\"params\":{\"newCloseFactorMantissa\":\"New close factor, scaled by 1e18\"}},\"setCollateralFactor(address,uint256,uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:error\":\"MarketNotListed error is thrown when the market is not listedInvalidCollateralFactor error is thrown when collateral factor is too highInvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factorPriceError is thrown when the oracle returns an invalid price for the asset\",\"custom:event\":\"Emits NewCollateralFactor when collateral factor is updated and NewLiquidationThreshold when liquidation threshold is updated\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newCollateralFactorMantissa\":\"The new collateral factor, scaled by 1e18\",\"newLiquidationThresholdMantissa\":\"The new liquidation threshold, scaled by 1e18\",\"vToken\":\"The market to set the factor on\"}},\"setLiquidationIncentive(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:event\":\"Emits NewLiquidationIncentive on success\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newLiquidationIncentiveMantissa\":\"New liquidationIncentive scaled by 1e18\"}},\"setMarketBorrowCaps(address[],uint256[])\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManagerA borrow cap of type(uint256).max corresponds to unlimited borrowing.Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed until the total borrows amount goes below the new borrow cap\",\"params\":{\"newBorrowCaps\":\"The new borrow cap values in underlying to be set. A value of type(uint256).max corresponds to unlimited borrowing.\",\"vTokens\":\"The addresses of the markets (tokens) to change the borrow caps for\"}},\"setMarketSupplyCaps(address[],uint256[])\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManagerA supply cap of type(uint256).max corresponds to unlimited supply.Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed until the total supplies amount goes below the new supply cap\",\"params\":{\"newSupplyCaps\":\"The new supply cap values in underlying to be set. A value of type(uint256).max corresponds to unlimited supply.\",\"vTokens\":\"The addresses of the markets (tokens) to change the supply caps for\"}},\"setMaxLoopsLimit(uint256)\":{\"params\":{\"limit\":\"Limit for the max loops can execute at a time\"}},\"setMinLiquidatableCollateral(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newMinLiquidatableCollateral\":\"The new min liquidatable collateral (in USD).\"}},\"setPriceOracle(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when the new oracle address is zero\",\"custom:event\":\"Emits NewPriceOracle on success\",\"details\":\"Only callable by the admin\",\"params\":{\"newOracle\":\"Address of the new price oracle to set\"}},\"supportMarket(address)\":{\"custom:access\":\"Only PoolRegistry\",\"custom:error\":\"MarketAlreadyListed is thrown if the market is already listed in this pool\",\"details\":\"Only callable by the PoolRegistry\",\"params\":{\"vToken\":\"The address of the market (token) to list\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"updatePrices(address)\":{\"params\":{\"account\":\"Address of the account to get associated tokens with\"}}},\"stateVariables\":{\"poolRegistry\":{\"custom:oz-upgrades-unsafe-allow\":\"state-variable-immutable\"}},\"title\":\"Comptroller\",\"version\":1},\"userdoc\":{\"errors\":{\"ActionPaused(address,uint8)\":[{\"notice\":\"Thrown when trying to perform an action that is paused\"}],\"BorrowCapExceeded(address,uint256)\":[{\"notice\":\"Thrown if the borrow cap is exceeded\"}],\"ComptrollerMismatch()\":[{\"notice\":\"Thrown when a market has an unexpected comptroller\"}],\"InsufficientLiquidity()\":[{\"notice\":\"Thrown when the account doesn't have enough liquidity to redeem or borrow\"}],\"InsufficientShortfall()\":[{\"notice\":\"Thrown when trying to liquidate a healthy account\"}],\"InvalidCollateralFactor()\":[{\"notice\":\"Thrown when collateral factor exceeds the upper bound\"}],\"InvalidLiquidationThreshold()\":[{\"notice\":\"Thrown when liquidation threshold exceeds the collateral factor\"}],\"MarketAlreadyListed(address)\":[{\"notice\":\"Thrown when trying to add a market that is already listed\"}],\"MarketNotCollateral(address,address)\":[{\"notice\":\"Thrown when user is not member of market\"}],\"MarketNotListed(address)\":[{\"notice\":\"Thrown when the market is not listed\"}],\"MaxLoopsLimitExceeded(uint256,uint256)\":[{\"notice\":\"Thrown an error on maxLoopsLimit exceeds for any loop\"}],\"MinimalCollateralViolated(uint256,uint256)\":[{\"notice\":\"Thrown during the liquidation if user's total collateral amount is lower than a predefined threshold. In this case only batch liquidations (either liquidateAccount or healAccount) are available.\"}],\"NonzeroBorrowBalance()\":[{\"notice\":\"Thrown if the user is trying to exit a market in which they have an outstanding debt\"}],\"PriceError(address)\":[{\"notice\":\"Thrown when the oracle returns an invalid price for some asset\"}],\"SnapshotError(address,address)\":[{\"notice\":\"Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\"}],\"SupplyCapExceeded(address,uint256)\":[{\"notice\":\"Thrown if the supply cap is exceeded\"}],\"TooMuchRepay()\":[{\"notice\":\"Thrown when trying to repay more than allowed by close factor\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"Thrown when the action is prohibited by AccessControlManager\"}],\"UnexpectedSender(address,address)\":[{\"notice\":\"Thrown when the action is only available to specific sender, but the real sender was different\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"ActionPausedMarket(address,uint8,bool)\":{\"notice\":\"Emitted when an action is paused on a market\"},\"MarketEntered(address,address)\":{\"notice\":\"Emitted when an account enters a market\"},\"MarketExited(address,address)\":{\"notice\":\"Emitted when an account exits a market\"},\"MarketSupported(address)\":{\"notice\":\"Emitted when a market is supported\"},\"MaxLoopsLimitUpdated(uint256,uint256)\":{\"notice\":\"Emitted when max loops limit is set\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when access control manager contract address is changed\"},\"NewBorrowCap(address,uint256)\":{\"notice\":\"Emitted when borrow cap for a vToken is changed\"},\"NewCloseFactor(uint256,uint256)\":{\"notice\":\"Emitted when close factor is changed by admin\"},\"NewCollateralFactor(address,uint256,uint256)\":{\"notice\":\"Emitted when a collateral factor is changed by admin\"},\"NewLiquidationIncentive(uint256,uint256)\":{\"notice\":\"Emitted when liquidation incentive is changed by admin\"},\"NewLiquidationThreshold(address,uint256,uint256)\":{\"notice\":\"Emitted when liquidation threshold is changed by admin\"},\"NewMinLiquidatableCollateral(uint256,uint256)\":{\"notice\":\"Emitted when the collateral threshold (in USD) for non-batch liquidations is changed\"},\"NewPriceOracle(address,address)\":{\"notice\":\"Emitted when price oracle is changed\"},\"NewRewardsDistributor(address)\":{\"notice\":\"Emitted when a rewards distributor is added\"},\"NewSupplyCap(address,uint256)\":{\"notice\":\"Emitted when supply cap for a vToken is changed\"}},\"kind\":\"user\",\"methods\":{\"accessControlManager()\":{\"notice\":\"Returns the address of the access control manager contract\"},\"accountAssets(address,uint256)\":{\"notice\":\"Per-account mapping of \\\"assets you are in\\\"\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"addRewardsDistributor(address)\":{\"notice\":\"Add a new RewardsDistributor and initialize it with all markets\"},\"allMarkets(uint256)\":{\"notice\":\"A list of all markets\"},\"borrowCaps(address)\":{\"notice\":\"Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\"},\"checkMembership(address,address)\":{\"notice\":\"Returns whether the given account is entered in a given market\"},\"closeFactorMantissa()\":{\"notice\":\"Multiplier used to calculate the maximum repayAmount when liquidating a borrow\"},\"enterMarkets(address[])\":{\"notice\":\"Add assets to be included in account liquidity calculation; enabling them to be used as collateral\"},\"exitMarket(address)\":{\"notice\":\"Removes asset from sender's account liquidity calculation; disabling them as collateral\"},\"getAccountLiquidity(address)\":{\"notice\":\"Determine the current account liquidity with respect to liquidation threshold requirements\"},\"getAllMarkets()\":{\"notice\":\"Return all of the markets\"},\"getAssetsIn(address)\":{\"notice\":\"Returns the assets an account has entered\"},\"getBorrowingPower(address)\":{\"notice\":\"Determine the current account liquidity with respect to collateral requirements\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"notice\":\"Determine what the account liquidity would be if the given amounts were redeemed/borrowed\"},\"getRewardDistributors()\":{\"notice\":\"Return all reward distributors for this pool\"},\"getRewardsByMarket(address)\":{\"notice\":\"Returns reward speed given a vToken\"},\"healAccount(address)\":{\"notice\":\"Seizes all the remaining collateral, makes msg.sender repay the existing borrows, and treats the rest of the debt as bad debt (for each market). The sender has to repay a certain percentage of the debt, computed as collateral / (borrows * liquidationIncentive).\"},\"isComptroller()\":{\"notice\":\"A marker method that returns true for a valid Comptroller contract\"},\"isDeprecated(address)\":{\"notice\":\"Check if a vToken market has been deprecated\"},\"isMarketListed(address)\":{\"notice\":\"Check if a market is marked as listed (active)\"},\"liquidateAccount(address,(address,address,uint256)[])\":{\"notice\":\"Liquidates all borrows of the borrower. Callable only if the collateral is less than a predefined threshold, and the account collateral can be seized to cover all borrows. If the collateral is higher than the threshold, use regular liquidations. If the collateral is below the threshold, and the account is insolvent, use healAccount.\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"liquidationIncentiveMantissa()\":{\"notice\":\"Multiplier representing the discount on collateral that a liquidator receives\"},\"markets(address)\":{\"notice\":\"Official mapping of vTokens -> Market metadata\"},\"minLiquidatableCollateral()\":{\"notice\":\"Minimal collateral required for regular (non-batch) liquidations\"},\"oracle()\":{\"notice\":\"Oracle which gives the price of any given asset\"},\"preBorrowHook(address,address,uint256)\":{\"notice\":\"disable-eslint\"},\"preLiquidateHook(address,address,address,uint256,bool)\":{\"notice\":\"Checks if the liquidation should be allowed to occur\"},\"preMintHook(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to mint tokens in the given market\"},\"preRedeemHook(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to redeem tokens in the given market\"},\"preRepayHook(address,address)\":{\"notice\":\"Checks if the account should be allowed to repay a borrow in the given market\"},\"preSeizeHook(address,address,address,address)\":{\"notice\":\"Checks if the seizing of assets should be allowed to occur\"},\"preTransferHook(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to transfer tokens in the given market\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of AccessControlManager\"},\"setActionsPaused(address[],uint8[],bool)\":{\"notice\":\"Pause/unpause specified actions\"},\"setCloseFactor(uint256)\":{\"notice\":\"Sets the closeFactor to use when liquidating borrows\"},\"setCollateralFactor(address,uint256,uint256)\":{\"notice\":\"Sets the collateralFactor for a market\"},\"setLiquidationIncentive(uint256)\":{\"notice\":\"Sets liquidationIncentive\"},\"setMarketBorrowCaps(address[],uint256[])\":{\"notice\":\"Set the given borrow caps for the given vToken markets. 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 markets. Supply that brings total Supply to or above supply cap will revert.\"},\"setMaxLoopsLimit(uint256)\":{\"notice\":\"Set the for loop iteration limit to avoid DOS\"},\"setMinLiquidatableCollateral(uint256)\":{\"notice\":\"Set the given collateral threshold for non-batch liquidations. Regular liquidations will fail if the collateral amount is less than this threshold. Liquidators should use batch operations like liquidateAccount or healAccount.\"},\"setPriceOracle(address)\":{\"notice\":\"Sets a new price oracle for the Comptroller\"},\"supplyCaps(address)\":{\"notice\":\"Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\"},\"supportMarket(address)\":{\"notice\":\"Add the market to the markets mapping and set it as listed\"},\"updatePrices(address)\":{\"notice\":\"Update the prices of all the tokens associated with the provided account\"}},\"notice\":\"The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating, and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow, as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed the `minLiquidatableCollateral` for the `Comptroller`: - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool. - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic verifying that the repay amount does not exceed the close factor.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller.sol\":\"Comptroller\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address vToken) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address vToken,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x8ac0bda5d5789c320bf219dc6691eef0e6617e9653bc0e24f407a44e4281edda\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n address rewardToken = address(rewardsDistributors[i].rewardToken());\\n require(\\n rewardToken != address(_rewardsDistributor.rewardToken()),\\n \\\"distributor already exists with this reward\\\"\\n );\\n }\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f4a5c92970213ecb680e41cdbf8f35fc3a05129e8a978c4a77874c3fd0f8aca\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length,\\n \\\"RewardsDistributor::setRewardTokenSpeeds invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0xb3a75c647fa2c20cd868839622f10a0cdb411ba5adbec75b73f9f41721f74185\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b50604051620055bf380380620055bf833981016040819052620000349162000149565b6200003f816200005d565b6001600160a01b0381166080526200005662000088565b506200017b565b6001600160a01b03811662000085576040516342bcdf7f60e11b815260040160405180910390fd5b50565b600054610100900460ff1615620000f55760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161462000147576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200015c57600080fd5b81516001600160a01b03811681146200017457600080fd5b9392505050565b6080516154216200019e600039600081816106b20152612c5901526154216000f3fe608060405234801561001057600080fd5b506004361061035c5760003560e01c80638e6470ea116101d3578063c488847b11610104578063e30c3978116100a2578063e89d51ad1161007c578063e89d51ad14610807578063eade3eed1461081a578063ede4edd01461082d578063f2fde38b1461084057600080fd5b8063e30c3978146107da578063e85a2960146107eb578063e8755446146107fe57600080fd5b8063da35a26f116100de578063da35a26f14610798578063db5c65de146107ab578063dce15449146107b4578063df71403b146107c757600080fd5b8063c488847b1461074a578063cab4f84c14610772578063d136af441461078557600080fd5b8063afcff50f11610171578063b4a0bdf31161014b578063b4a0bdf3146106fc578063be26317e1461070d578063c0891ba914610717578063c29982381461072a57600080fd5b8063afcff50f146106ad578063b0772d0b146106d4578063b2068e84146106dc57600080fd5b8063929fe9a1116101ad578063929fe9a11461063357806394543c1514610674578063a843108114610687578063abfceffc1461069a57600080fd5b80638e6470ea146105bd5780638e8f294b146105d0578063921363951461062057600080fd5b8063528a174c116102ad57806361252fd11161024b57806379ba50971161022557806379ba50971461057e5780637dc0d1d01461058657806380d45a2d146105995780638da5cb5b146105ac57600080fd5b806361252fd11461054e5780636d0be88d14610563578063715018a61461057657600080fd5b806356aaee2d1161028757806356aaee2d146105025780635c21b6c5146105155780635cc4fdeb146105285780635ec88c791461053b57600080fd5b8063528a174c146104b157806352d84d1e146104c4578063530e784f146104ef57600080fd5b806324aaa2201161031a5780634a584432116102f45780634a584432146104475780634ada90af146104675780634e79238f14610470578063520b6c741461049e57600080fd5b806324aaa220146103f55780632bce219c146104085780633d98a1e51461041b57600080fd5b80627e3dd21461036157806302c3bcbb146103795780630e32cb86146103a757806312348e96146103bc578063186db48f146103cf5780631bc41f28146103e2575b600080fd5b60015b60405190151581526020015b60405180910390f35b6103996103873660046149bc565b60d16020526000908152604090205481565b604051908152602001610370565b6103ba6103b53660046149bc565b610853565b005b6103ba6103ca3660046149d9565b610867565b6103ba6103dd366004614a3e565b6109cd565b6103ba6103f0366004614aaa565b610b46565b6103ba610403366004614b14565b610f15565b6103ba610416366004614b98565b610fe2565b6103646104293660046149bc565b6001600160a01b0316600090815260cd602052604090205460ff1690565b6103996104553660046149bc565b60cf6020526000908152604090205481565b61039960cb5481565b61048361047e366004614c20565b6113c9565b60408051938452602084019290925290820152606001610370565b6103ba6104ac3660046149d9565b6113fa565b6104836104bf3660046149bc565b611458565b6104d76104d23660046149d9565b611483565b6040516001600160a01b039091168152602001610370565b6103ba6104fd3660046149bc565b6114ad565b6103ba6105103660046149bc565b611511565b6103ba6105233660046149bc565b611847565b6103ba610536366004614c66565b611973565b6104836105493660046149bc565b611bb0565b610556611bc2565b6040516103709190614c9b565b6103ba610571366004614ce8565b611c24565b6103ba611d9a565b6103ba611dae565b60c9546104d7906001600160a01b031681565b6103ba6105a73660046149d9565b611e25565b6033546001600160a01b03166104d7565b6103ba6105cb366004614d39565b611e36565b6106036105de3660046149bc565b60cd6020526000908152604090208054600182015460029092015460ff909116919083565b604080519315158452602084019290925290820152606001610370565b6103ba61062e3660046149bc565b611f4c565b610364610641366004614d7a565b6001600160a01b03808216600090815260cd60209081526040808320938616835260039093019052205460ff1692915050565b6103646106823660046149bc565b612332565b6103ba6106953660046149d9565b6123db565b6105566106a83660046149bc565b6124c9565b6104d77f000000000000000000000000000000000000000000000000000000000000000081565b61055661253f565b6106ef6106ea3660046149bc565b61259f565b6040516103709190614db3565b6097546001600160a01b03166104d7565b6103996101075481565b6103ba610725366004614d39565b6127e2565b61073d610738366004614e2b565b612a72565b6040516103709190614ef0565b61075d610758366004614d39565b612b29565b60408051928352602083019190915201610370565b6103ba6107803660046149bc565b612c54565b6103ba610793366004614a3e565b612e88565b6103ba6107a6366004614f28565b613045565b61039960d05481565b6104d76107c2366004614f4d565b613166565b6103ba6107d5366004614d39565b61319e565b6065546001600160a01b03166104d7565b6103646107f9366004614f88565b61355b565b61039960ca5481565b6103ba610815366004614fbd565b6135b2565b6103ba610828366004614d7a565b6137a2565b61039961083b3660046149bc565b6139dc565b6103ba61084e3660046149bc565b613c4e565b61085b613cbf565b61086481613d19565b50565b6108a56040518060400160405280601781526020017f736574436c6f7365466163746f722875696e7432353629000000000000000000815250613dd0565b80670c7d713b49da000010156109195760405162461bcd60e51b815260206004820152602e60248201527f436c6f736520666163746f722067726561746572207468616e206d6178696d7560448201526d369031b637b9b2903330b1ba37b960911b60648201526084015b60405180910390fd5b8066b1a2bc2ec5000011156109875760405162461bcd60e51b815260206004820152602e60248201527f436c6f736520666163746f7220736d616c6c6572207468616e206d696e696d7560448201526d369031b637b9b2903330b1ba37b960911b6064820152608401610910565b60ca80549082905560408051828152602081018490527f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd991015b60405180910390a15050565b6109ee60405180606001604052806028815260200161532160289139613dd0565b828181158015906109fe57508082145b610a3a5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b6044820152606401610910565b610a4382613e6e565b60005b82811015610b3d57848482818110610a6057610a60615017565b9050602002013560cf6000898985818110610a7d57610a7d615017565b9050602002016020810190610a9291906149bc565b6001600160a01b03168152602081019190915260400160002055868682818110610abe57610abe615017565b9050602002016020810190610ad391906149bc565b6001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110610b0f57610b0f615017565b90506020020135604051610b2591815260200190565b60405180910390a2610b3681615043565b9050610a46565b50505050505050565b610b51846004613ea1565b6001600160a01b038416600090815260cd60205260409020805460ff16610b9657604051635a9a1eb960e11b81526001600160a01b0386166004820152602401610910565b306001600160a01b03851603610c3e57306001600160a01b0316856001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c12919061505c565b6001600160a01b031614610c3957604051630c73eb0560e01b815260040160405180910390fd5b610d76565b6001600160a01b038416600090815260cd602052604090205460ff16610c8257604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b836001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce4919061505c565b6001600160a01b0316856001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f919061505c565b6001600160a01b031614610d7657604051630c73eb0560e01b815260040160405180910390fd5b6001600160a01b038216600090815260038201602052604090205460ff16610db5578482604051630cdfb2db60e31b8152600401610910929190615079565b60d35460005b81811015610b3d57600060d38281548110610dd857610dd8615017565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b038a8116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015610e2b57600080fd5b505af1158015610e3f573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150610e71908b908990600401615079565b600060405180830381600087803b158015610e8b57600080fd5b505af1158015610e9f573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150610ed1908b908a90600401615079565b600060405180830381600087803b158015610eeb57600080fd5b505af1158015610eff573d6000803e3d6000fd5b505050505080610f0e90615043565b9050610dbb565b610f366040518060600160405280602a815260200161539a602a9139613dd0565b8382610f4a610f458284615093565b613e6e565b60005b82811015610fd85760005b82811015610fc757610fb7898984818110610f7557610f75615017565b9050602002016020810190610f8a91906149bc565b888884818110610f9c57610f9c615017565b9050602002016020810190610fb191906150b2565b87613ecd565b610fc081615043565b9050610f58565b50610fd181615043565b9050610f4d565b5050505050505050565b6000610ff084613fdb61400f565b905060d054816000015111156110275760d0548151604051631a451c0f60e21b815260048101929092526024820152604401610910565b6000611047604051806020016040528060cb54815250836040015161405e565b82519091508110611078578151604051632c1f8ef160e21b8152610910918391600401918252602082015260400190565b8160a0015160000361109d5760405163095bf33360e01b815260040160405180910390fd5b826110ac610f456002836150cd565b60005b818110156112a45760cd60008787848181106110cd576110cd615017565b90506060020160200160208101906110e591906149bc565b6001600160a01b0316815260208101919091526040016000205460ff166111555785858281811061111857611118615017565b905060600201602001602081019061113091906149bc565b604051635a9a1eb960e11b81526001600160a01b039091166004820152602401610910565b60cd600087878481811061116b5761116b615017565b61118192602060609092020190810191506149bc565b6001600160a01b0316815260208101919091526040016000205460ff166111ca578585828181106111b4576111b4615017565b61113092602060609092020190810191506149bc565b368686838181106111dd576111dd615017565b90506060020190508060200160208101906111f891906149bc565b6001600160a01b0316638bbdb6db338a604085013561121a60208701876149bc565b60405160e086901b6001600160e01b03191681526001600160a01b0394851660048201529284166024840152604483019190915290911660648201526001608482015260a401600060405180830381600087803b15801561127a57600080fd5b505af115801561128e573d6000803e3d6000fd5b50505050508061129d90615043565b90506110af565b506001600160a01b038616600090815260cc602090815260408083208054825181850281018501909352808352919290919083018282801561130f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112f1575b505083519394506000925050505b818110156113be57600061134a84838151811061133c5761133c615017565b60200260200101518b61407e565b5091505080156113ad5760405162461bcd60e51b815260206004820152602860248201527f4e6f6e7a65726f20626f72726f772062616c616e6365206166746572206c69716044820152673ab4b230ba34b7b760c11b6064820152608401610910565b506113b781615043565b905061131d565b505050505050505050565b6000806000806113de88888888614125614159565b608081015160a09091015160009a919950975095505050505050565b61141b60405180606001604052806025815260200161534960259139613dd0565b60d080549082905560408051828152602081018490527eb4f4f153ad7f1397564a8830fef092481e8cf6a2cd3ff04f96d10ba51200a591016109c1565b60008060008061146a8561412561400f565b608081015160a090910151600097919650945092505050565b60ce818154811061149357600080fd5b6000918252602090912001546001600160a01b0316905081565b6114b5613cbf565b6114be8161438e565b60c980546001600160a01b038381166001600160a01b03198316179092556040519116907fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22906109c19083908590615079565b611519613cbf565b6001600160a01b038116600090815260d4602052604090205460ff16156115735760405162461bcd60e51b815260206004820152600e60248201526d616c72656164792065786973747360901b6044820152606401610910565b60d35460005b818110156116f157600060d3828154811061159657611596615017565b600091825260209182902001546040805163f7c618c160e01b815290516001600160a01b039092169263f7c618c1926004808401938290030181865afa1580156115e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611608919061505c565b9050836001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611648573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166c919061505c565b6001600160a01b0316816001600160a01b0316036116e05760405162461bcd60e51b815260206004820152602b60248201527f6469737472696275746f7220616c72656164792065786973747320776974682060448201526a1d1a1a5cc81c995dd85c9960aa1b6064820152608401610910565b506116ea81615043565b9050611579565b5060d354611703610f458260016150ef565b60d3805460018082019092557f915c3eb987b20e1af620c1403197bf687fb7f18513b3a73fde6e78c7072c41a60180546001600160a01b0319166001600160a01b038616908117909155600090815260d460205260408120805460ff191690921790915560ce54905b8181101561180c57846001600160a01b0316632a869a4d60ce838154811061179657611796615017565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401600060405180830381600087803b1580156117e357600080fd5b505af11580156117f7573d6000803e3d6000fd5b505050508061180590615043565b905061176c565b506040516001600160a01b038516907f058fa9577dc29aece41d41c2d3bff2ed4e8d5085762198e8f7faab35039555da90600090a250505050565b6001600160a01b038116600090815260cc60209081526040808320805482518185028101850190935280835291929091908301828280156118b157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611893575b5050835160c954949550936001600160a01b0316925060009150505b8281101561196c57816001600160a01b03166396e85ced8583815181106118f6576118f6615017565b60200260200101516040518263ffffffff1660e01b815260040161192991906001600160a01b0391909116815260200190565b600060405180830381600087803b15801561194357600080fd5b505af1158015611957573d6000803e3d6000fd5b505050508061196590615043565b90506118cd565b5050505050565b6119946040518060600160405280602c815260200161536e602c9139613dd0565b6001600160a01b038316600090815260cd60205260409020805460ff166119d957604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b670c7d713b49da0000831115611a02576040516302f22cad60e61b815260040160405180910390fd5b670de0b6b3a7640000821115611a2a5760405162f9474b60e61b815260040160405180910390fd5b82821015611a4a5760405162f9474b60e61b815260040160405180910390fd5b8215801590611ac4575060c95460405163fc57d4df60e01b81526001600160a01b0386811660048301529091169063fc57d4df90602401602060405180830381865afa158015611a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac29190615107565b155b15611aec5760405162e52a7d60e41b81526001600160a01b0385166004820152602401610910565b6001810154838114611b4a5760018201849055604080516001600160a01b0387168152602081018390529081018590527f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59060600160405180910390a15b6002820154838114611ba85760028301849055604080516001600160a01b0388168152602081018390529081018590527f9e92c7d5fef69846094f3ddcadcb9402c6ba469c461368714f1cabd8ef48b5919060600160405180910390a15b505050505050565b60008060008061146a85613fdb61400f565b606060d3805480602002602001604051908101604052809291908181526020018280548015611c1a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611bfc575b5050505050905090565b611c2f846006613ea1565b611c3a8484836143b5565b60d35460005b81811015611ba857600060d38281548110611c5d57611c5d615017565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03898116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015611cb057600080fd5b505af1158015611cc4573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611cf6908a908a90600401615079565b600060405180830381600087803b158015611d1057600080fd5b505af1158015611d24573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611d56908a908990600401615079565b600060405180830381600087803b158015611d7057600080fd5b505af1158015611d84573d6000803e3d6000fd5b505050505080611d9390615043565b9050611c40565b611da2613cbf565b611dac6000614463565b565b60655433906001600160a01b03168114611e1c5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610910565b61086481614463565b611e2d613cbf565b6108648161447c565b611e41836001613ea1565b611e4c8383836143b5565b60d35460005b8181101561196c57600060d38281548110611e6f57611e6f615017565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03888116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015611ec257600080fd5b505af1158015611ed6573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611f089089908990600401615079565b600060405180830381600087803b158015611f2257600080fd5b505af1158015611f36573d6000803e3d6000fd5b505050505080611f4590615043565b9050611e52565b6001600160a01b038116600090815260cc6020908152604080832080548251818502810185019093528083529192909190830182828015611fb657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611f98575b5050835160c954949550933393506001600160a01b03169150600090505b838110156120f157848181518110611fee57611fee615017565b60200260200101516001600160a01b031663a6afed956040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120599190615107565b50816001600160a01b03166396e85ced86838151811061207b5761207b615017565b60200260200101516040518263ffffffff1660e01b81526004016120ae91906001600160a01b0391909116815260200190565b600060405180830381600087803b1580156120c857600080fd5b505af11580156120dc573d6000803e3d6000fd5b50505050806120ea90615043565b9050611fd4565b5050600061210185613fdb61400f565b905060d054816000015111156121385760d0548151604051631a451c0f60e21b815260048101929092526024820152604401610910565b8060a0015160000361215d5760405163095bf33360e01b815260040160405180910390fd5b60408051602080820183528351825282518082018452848401518152835191820190935260cb54815290916000916121959190614518565b905060006121a38383614560565b90506121c76040518060200160405280670de0b6b3a7640000815250825190511090565b156121f25781518351604051631a451c0f60e21b815260048101929092526024820152604401610910565b60005b868110156113be57600088828151811061221157612211615017565b60200260200101519050600080612228838d61407e565b50915091506000612239868361405e565b905082156122ac5760405163b2a02ff160e01b81526001600160a01b038b811660048301528e811660248301526044820185905285169063b2a02ff190606401600060405180830381600087803b15801561229357600080fd5b505af11580156122a7573d6000803e3d6000fd5b505050505b811561231d5760405163227f37ff60e11b81526001600160a01b038b811660048301528e81166024830152604482018390528516906344fe6ffe90606401600060405180830381600087803b15801561230457600080fd5b505af1158015612318573d6000803e3d6000fd5b505050505b505050508061232b90615043565b90506121f5565b6001600160a01b038116600090815260cd6020526040812060010154158015612361575061236182600261355b565b80156123d55750670de0b6b3a7640000826001600160a01b031663173b99046040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d39190615107565b145b92915050565b670de0b6b3a764000081101561244d5760405162461bcd60e51b815260206004820152603160248201527f6c69717569646174696f6e20696e63656e746976652073686f756c64206265206044820152700cee4cac2e8cae440e8d0c2dc4062ca627607b1b6064820152608401610910565b61248b6040518060400160405280602081526020017f7365744c69717569646174696f6e496e63656e746976652875696e7432353629815250613dd0565b60cb80549082905560408051828152602081018490527faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec131691016109c1565b6001600160a01b038116600090815260cc6020908152604080832080548251818502810185019093528083526060949383018282801561253257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612514575b5093979650505050505050565b606060ce805480602002602001604051908101604052809291908181526020018280548015611c1a576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311611bfc575050505050905090565b60d3546060908067ffffffffffffffff8111156125be576125be614e15565b60405190808252806020026020018201604052801561261c57816020015b612609604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b8152602001906001900390816125dc5790505b50915060005b818110156127db57600060d3828154811061263f5761263f615017565b60009182526020808320909101546040805163f7c618c160e01b815290516001600160a01b039092169450849263f7c618c1926004808401938290030181865afa158015612691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b5919061505c565b604080516060810182526001600160a01b0380841682529151631d31307360e21b815289831660048201529293509160208301918516906374c4c1cc90602401602060405180830381865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127369190615107565b8152604051637c05a7c560e01b81526001600160a01b038981166004830152602090920191851690637c05a7c590602401602060405180830381865afa158015612784573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a89190615107565b8152508584815181106127bd576127bd615017565b60200260200101819052505050806127d490615043565b9050612622565b5050919050565b6127ed836000613ea1565b6001600160a01b038316600090815260cd602052604090205460ff1661283157604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b038316600090815260d160205260409020546000198114612972576000846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b79190615107565b905060006040518060200160405280876001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612904573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129289190615107565b90529050600061293982848761459a565b90508381111561296e5760405163db33be3d60e01b81526001600160a01b038816600482015260248101859052604401610910565b5050505b60d35460005b81811015611ba857600060d3828154811061299557612995615017565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03898116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b1580156129e857600080fd5b505af11580156129fc573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150612a2e908a908a90600401615079565b600060405180830381600087803b158015612a4857600080fd5b505af1158015612a5c573d6000803e3d6000fd5b505050505080612a6b90615043565b9050612978565b805160609060008167ffffffffffffffff811115612a9257612a92614e15565b604051908082528060200260200182016040528015612abb578160200160208202803683370190505b50905060005b82811015612b21576000858281518110612add57612add615017565b60200260200101519050612af181336145c4565b6000838381518110612b0557612b05615017565b602090810291909101015250612b1a81615043565b9050612ac1565b509392505050565b6000806000612b37866146c0565b90506000612b44866146c0565b90506000866001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612baa9190615107565b90506000612bc46040518060200160405280600081525090565b60408051602080820183526000808352835180830185529081528351808301855260cb54815284519283019094528882529192612c0091614518565b9250612c28604051806020016040528088815250604051806020016040528088815250614518565b9150612c348383614560565b9050612c40818b61405e565b60009d909c509a5050505050505050505050565b612c7d7f000000000000000000000000000000000000000000000000000000000000000061475f565b6001600160a01b038116600090815260cd602052604090205460ff1615612cc25760405163d005ce4760e01b81526001600160a01b0382166004820152602401610910565b806001600160a01b0316633d9ea3a16040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d249190615120565b612d705760405162461bcd60e51b815260206004820152601b60248201527f436f6d7074726f6c6c65723a20496e76616c69642076546f6b656e00000000006044820152606401610910565b6001600160a01b038116600090815260cd60205260408120805460ff19166001908117825581018290556002810191909155612dab8261478c565b60d35460005b81811015612e455760d38181548110612dcc57612dcc615017565b600091825260209091200154604051632a869a4d60e01b81526001600160a01b03868116600483015290911690632a869a4d90602401600060405180830381600087803b158015612e1c57600080fd5b505af1158015612e30573d6000803e3d6000fd5b5050505080612e3e90615043565b9050612db1565b506040516001600160a01b03841681527faf16ad15f9e29d5140e8e81a30a92a755aa8edff3d301053c84392b70c0d09a3906020015b60405180910390a1505050565b612ea96040518060600160405280602881526020016153c460289139613dd0565b826000819003612ef75760405162461bcd60e51b8152602060048201526019602482015278696e76616c6964206e756d626572206f66206d61726b65747360381b6044820152606401610910565b808214612f425760405162461bcd60e51b8152602060048201526019602482015278696e76616c6964206e756d626572206f66206d61726b65747360381b6044820152606401610910565b612f4b81613e6e565b60005b81811015611ba857838382818110612f6857612f68615017565b9050602002013560d16000888885818110612f8557612f85615017565b9050602002016020810190612f9a91906149bc565b6001600160a01b03168152602081019190915260400160002055858582818110612fc657612fc6615017565b9050602002016020810190612fdb91906149bc565b6001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f885858481811061301757613017615017565b9050602002013560405161302d91815260200190565b60405180910390a261303e81615043565b9050612f4e565b600054610100900460ff16158080156130655750600054600160ff909116105b8061307f5750303b15801561307f575060005460ff166001145b6130e25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610910565b6000805460ff191660011790558015613105576000805461ff0019166101001790555b61310d61485b565b6131168261488a565b61311f8361447c565b8015613161576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001612e7b565b505050565b60cc602052816000526040600020818154811061318257600080fd5b6000918252602090912001546001600160a01b03169150829050565b6131a9836002613ea1565b6001600160a01b038316600090815260cd602052604090205460ff166131ed57604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b03808416600090815260cd60209081526040808320938616835260039093019052205460ff16613231576132278361475f565b61323133836145c4565b61323a82611847565b60c95460405163fc57d4df60e01b81526001600160a01b0385811660048301529091169063fc57d4df90602401602060405180830381865afa158015613284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a89190615107565b6000036132d25760405162e52a7d60e41b81526001600160a01b0384166004820152602401610910565b6001600160a01b038316600090815260cf6020526040902054600019811461339e576000846001600160a01b03166347bd37186040518163ffffffff1660e01b8152600401602060405180830381865afa158015613334573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133589190615107565b9050600061336684836150ef565b90508281111561339b57604051632e649eed60e01b81526001600160a01b038716600482015260248101849052604401610910565b50505b60006133b08486600086614125614159565b60a0810151909150156133d65760405163bb55fd2760e01b815260040160405180910390fd5b60006040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134459190615107565b905260d35490915060005b81811015610fd857600060d3828154811061346d5761346d615017565b600091825260209091200154604051632352607960e01b81526001600160a01b038b811660048301528651602483015290911691508190632352607990604401600060405180830381600087803b1580156134c757600080fd5b505af11580156134db573d6000803e3d6000fd5b5050604051636a95ddef60e01b81526001600160a01b038c811660048301528b811660248301528751604483015284169250636a95ddef9150606401600060405180830381600087803b15801561353157600080fd5b505af1158015613545573d6000803e3d6000fd5b50505050508061355490615043565b9050613450565b6001600160a01b038216600090815260d260205260408120818360088111156135865761358661513d565b60088111156135975761359761513d565b815260208101919091526040016000205460ff169392505050565b6135bd856005613ea1565b6135c683611847565b6001600160a01b038516600090815260cd602052604090205460ff1661360a57604051635a9a1eb960e11b81526001600160a01b0386166004820152602401610910565b6001600160a01b038416600090815260cd602052604090205460ff1661364e57604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b6040516395dd919360e01b81526001600160a01b038481166004830152600091908716906395dd919390602401602060405180830381865afa158015613698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136bc9190615107565b905081806136ce57506136ce86612332565b156136fa57808311156136f45760405163e46c155960e01b815260040160405180910390fd5b5061196c565b600061370885613fdb61400f565b905060d05481600001511161373e5760d0548151604051636e61bb0560e11b815260048101929092526024820152604401610910565b8060a001516000036137635760405163095bf33360e01b815260040160405180910390fd5b600061377f604051806020016040528060ca548152508461405e565b905080851115610fd85760405163e46c155960e01b815260040160405180910390fd5b6137ad826003613ea1565b60c9546040516396e85ced60e01b81526001600160a01b038481166004830152909116906396e85ced90602401600060405180830381600087803b1580156137f457600080fd5b505af1158015613808573d6000803e3d6000fd5b505050506001600160a01b038216600090815260cd602052604090205460ff1661385057604051635a9a1eb960e11b81526001600160a01b0383166004820152602401610910565b60d35460005b818110156139d65760006040518060200160405280866001600160a01b031663aa5af0fd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138cd9190615107565b8152509050600060d383815481106138e7576138e7615017565b600091825260209091200154604051632352607960e01b81526001600160a01b0388811660048301528451602483015290911691508190632352607990604401600060405180830381600087803b15801561394157600080fd5b505af1158015613955573d6000803e3d6000fd5b5050604051636a95ddef60e01b81526001600160a01b03898116600483015288811660248301528551604483015284169250636a95ddef9150606401600060405180830381600087803b1580156139ab57600080fd5b505af11580156139bf573d6000803e3d6000fd5b505050505050806139cf90615043565b9050613856565b50505050565b60006139e9826008613ea1565b816000806139f7833361407e565b509150915080600014613a1d5760405163f8a5d66d60e01b815260040160405180910390fd5b613a288533846143b5565b6001600160a01b038316600090815260cd60209081526040808320338452600381019092529091205460ff16613a645750600095945050505050565b3360009081526003820160209081526040808320805460ff1916905560cc825280832080548251818502810185019093528083529192909190830182828015613ad657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613ab8575b5050835193945083925060009150505b82811015613b3857876001600160a01b0316848281518110613b0a57613b0a615017565b60200260200101516001600160a01b031603613b2857809150613b38565b613b3181615043565b9050613ae6565b50818110613b4857613b48615153565b33600090815260cc6020526040902080548190613b6790600190615169565b81548110613b7757613b77615017565b9060005260206000200160009054906101000a90046001600160a01b0316818381548110613ba757613ba7615017565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080805480613be557613be5615180565b600082815260208120820160001990810180546001600160a01b031916905590910190915560405133916001600160a01b038b16917fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d9190a35060009998505050505050505050565b613c56613cbf565b606580546001600160a01b0383166001600160a01b03199091168117909155613c876033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b03163314611dac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610910565b6001600160a01b038116613d7d5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b6064820152608401610910565b609780546001600160a01b038381166001600160a01b03198316179092556040519116907f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0906109c19083908590615079565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab90613e0390339086906004016151e3565b602060405180830381865afa158015613e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e449190615120565b905080613e6a57333083604051634a3fa29360e01b815260040161091093929190615207565b5050565b61010754811115610864576101075460405163792bfb1b60e11b8152600481019190915260248101829052604401610910565b613eab828261355b565b15613e6a5781816040516313b3ccb160e31b8152600401610910929190615255565b6001600160a01b038316600090815260cd602052604090205460ff16613f465760405162461bcd60e51b815260206004820152602860248201527f63616e6e6f742070617573652061206d61726b65742074686174206973206e6f6044820152671d081b1a5cdd195960c21b6064820152608401610910565b6001600160a01b038316600090815260d2602052604081208291846008811115613f7257613f7261513d565b6008811115613f8357613f8361513d565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d838383604051612e7b93929190615272565b6040805160208082018352600091829052825180820184526001600160a01b0394909416825260cd90522060020154815290565b6140486040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61405783600080600086614159565b9392505050565b60008061406b84846148b1565b9050614076816148d9565b949350505050565b6040516361bfb47160e11b81526001600160a01b03828116600483015260009182918291829187169063c37f68e290602401608060405180830381865afa1580156140cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140f1919061529f565b919650945092509050801561411d57858560405163015e34d960e61b8152600401610910929190615079565b509250925092565b6040805160208082018352600091829052825180820184526001600160a01b0394909416825260cd90522060010154815290565b6141926040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6001600160a01b038616600090815260cc60209081526040808320805482518185028101850190935280835291929091908301828280156141fc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116141de575b505083519394506000925050505b8181101561433057600083828151811061422657614226615017565b60200260200101519050600080600061423f848e61407e565b9250925092506000604051806020016040528061425b876146c0565b8152509050600061427a60405180602001604052808581525083614518565b9050600061429461428e888e63ffffffff16565b83614518565b90506142a581878d6020015161459a565b60208c01528a516142b9908390889061459a565b8b5260408b01516142cd908490879061459a565b8b60400181815250508e6001600160a01b0316876001600160a01b031603614318576142fe818f8d6060015161459a565b60608c018190526143129084908f9061459a565b60608c01525b505050505050508061432990615043565b905061420a565b5060008360600151846040015161434791906150ef565b9050808460200151111561436e5760208401518190036080850152600060a0850152614382565b600060808501526020840151810360a08501525b50505095945050505050565b6001600160a01b038116610864576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b038316600090815260cd60205260409020805460ff166143fa57604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b6001600160a01b038316600090815260038201602052604090205460ff166144225750505050565b61442b83611847565b600061443d8486856000614125614159565b60a08101519091501561196c5760405163bb55fd2760e01b815260040160405180910390fd5b606580546001600160a01b0319169055610864816148f1565b6101075481116144d95760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b6064820152608401610910565b61010780549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa91016109c1565b6040805160208101909152600081526040518060200160405280670de0b6b3a764000061454d86600001518660000151614943565b61455791906150cd565b90529392505050565b60408051602081019091526000815260405180602001604052806145576145938660000151670de0b6b3a7640000614943565b855161494f565b6000806145a785856148b1565b90506145bb6145b5826148d9565b8461495b565b95945050505050565b6145cf826007613ea1565b6001600160a01b038216600090815260cd60205260409020805460ff1661461457604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b038216600090815260038201602052604090205460ff161561463c57505050565b6001600160a01b0380831660008181526003840160209081526040808320805460ff1916600190811790915560cc835281842080549182018155845291832090910180549488166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a3505050565b60c95460405163fc57d4df60e01b81526001600160a01b038381166004830152600092839291169063fc57d4df90602401602060405180830381865afa15801561470e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147329190615107565b9050806000036123d55760405162e52a7d60e41b81526001600160a01b0384166004820152602401610910565b336001600160a01b03821614610864578033604051634e9383fb60e11b8152600401610910929190615079565b60ce5460005b8181101561480557826001600160a01b031660ce82815481106147b7576147b7615017565b6000918252602090912001546001600160a01b0316036147f55760405163d005ce4760e01b81526001600160a01b0384166004820152602401610910565b6147fe81615043565b9050614792565b505060ce805460018101825560008290527fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a0180546001600160a01b0319166001600160a01b03841617905554613e6a81613e6e565b600054610100900460ff166148825760405162461bcd60e51b8152600401610910906152d5565b611dac614967565b600054610100900460ff1661085b5760405162461bcd60e51b8152600401610910906152d5565b6040805160208101909152600081526040518060200160405280614557856000015185614943565b80516000906123d590670de0b6b3a7640000906150cd565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006140578284615093565b600061405782846150cd565b600061405782846150ef565b600054610100900460ff1661498e5760405162461bcd60e51b8152600401610910906152d5565b611dac33614463565b6001600160a01b038116811461086457600080fd5b80356149b781614997565b919050565b6000602082840312156149ce57600080fd5b813561405781614997565b6000602082840312156149eb57600080fd5b5035919050565b60008083601f840112614a0457600080fd5b50813567ffffffffffffffff811115614a1c57600080fd5b6020830191508360208260051b8501011115614a3757600080fd5b9250929050565b60008060008060408587031215614a5457600080fd5b843567ffffffffffffffff80821115614a6c57600080fd5b614a78888389016149f2565b90965094506020870135915080821115614a9157600080fd5b50614a9e878288016149f2565b95989497509550505050565b60008060008060808587031215614ac057600080fd5b8435614acb81614997565b93506020850135614adb81614997565b92506040850135614aeb81614997565b91506060850135614afb81614997565b939692955090935050565b801515811461086457600080fd5b600080600080600060608688031215614b2c57600080fd5b853567ffffffffffffffff80821115614b4457600080fd5b614b5089838a016149f2565b90975095506020880135915080821115614b6957600080fd5b50614b76888289016149f2565b9094509250506040860135614b8a81614b06565b809150509295509295909350565b600080600060408486031215614bad57600080fd5b8335614bb881614997565b9250602084013567ffffffffffffffff80821115614bd557600080fd5b818601915086601f830112614be957600080fd5b813581811115614bf857600080fd5b876020606083028501011115614c0d57600080fd5b6020830194508093505050509250925092565b60008060008060808587031215614c3657600080fd5b8435614c4181614997565b93506020850135614c5181614997565b93969395505050506040820135916060013590565b600080600060608486031215614c7b57600080fd5b8335614c8681614997565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015614cdc5783516001600160a01b031683529284019291840191600101614cb7565b50909695505050505050565b60008060008060808587031215614cfe57600080fd5b8435614d0981614997565b93506020850135614d1981614997565b92506040850135614d2981614997565b9396929550929360600135925050565b600080600060608486031215614d4e57600080fd5b8335614d5981614997565b92506020840135614d6981614997565b929592945050506040919091013590565b60008060408385031215614d8d57600080fd5b8235614d9881614997565b91506020830135614da881614997565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015614e0857815180516001600160a01b0316855286810151878601528501518585015260609093019290850190600101614dd0565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215614e3e57600080fd5b823567ffffffffffffffff80821115614e5657600080fd5b818501915085601f830112614e6a57600080fd5b813581811115614e7c57614e7c614e15565b8060051b604051601f19603f83011681018181108582111715614ea157614ea1614e15565b604052918252848201925083810185019188831115614ebf57600080fd5b938501935b82851015614ee457614ed5856149ac565b84529385019392850192614ec4565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614cdc57835183529284019291840191600101614f0c565b60008060408385031215614f3b57600080fd5b823591506020830135614da881614997565b60008060408385031215614f6057600080fd5b8235614f6b81614997565b946020939093013593505050565b8035600981106149b757600080fd5b60008060408385031215614f9b57600080fd5b8235614fa681614997565b9150614fb460208401614f79565b90509250929050565b600080600080600060a08688031215614fd557600080fd5b8535614fe081614997565b94506020860135614ff081614997565b9350604086013561500081614997565b9250606086013591506080860135614b8a81614b06565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016150555761505561502d565b5060010190565b60006020828403121561506e57600080fd5b815161405781614997565b6001600160a01b0392831681529116602082015260400190565b60008160001904831182151516156150ad576150ad61502d565b500290565b6000602082840312156150c457600080fd5b61405782614f79565b6000826150ea57634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156151025761510261502d565b500190565b60006020828403121561511957600080fd5b5051919050565b60006020828403121561513257600080fd5b815161405781614b06565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b60008282101561517b5761517b61502d565b500390565b634e487b7160e01b600052603160045260246000fd5b6000815180845260005b818110156151bc576020818501810151868301820152016151a0565b818111156151ce576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038316815260406020820181905260009061407690830184615196565b6001600160a01b038481168252831660208201526060604082018190526000906145bb90830184615196565b6009811061525157634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b0383168152604081016140576020830184615233565b6001600160a01b03841681526060810161528f6020830185615233565b8215156040830152949350505050565b600080600080608085870312156152b557600080fd5b505082516020840151604085015160609095015191969095509092509050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d297365744d696e4c6971756964617461626c65436f6c6c61746572616c2875696e7432353629736574436f6c6c61746572616c466163746f7228616464726573732c75696e743235362c75696e7432353629736574416374696f6e7350617573656428616464726573735b5d2c75696e743235365b5d2c626f6f6c297365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d29a26469706673582212202bcb0fe3478fc86c1351748222cd27e55828f204dabec416b9e29c89f475b53d64736f6c634300080d0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061035c5760003560e01c80638e6470ea116101d3578063c488847b11610104578063e30c3978116100a2578063e89d51ad1161007c578063e89d51ad14610807578063eade3eed1461081a578063ede4edd01461082d578063f2fde38b1461084057600080fd5b8063e30c3978146107da578063e85a2960146107eb578063e8755446146107fe57600080fd5b8063da35a26f116100de578063da35a26f14610798578063db5c65de146107ab578063dce15449146107b4578063df71403b146107c757600080fd5b8063c488847b1461074a578063cab4f84c14610772578063d136af441461078557600080fd5b8063afcff50f11610171578063b4a0bdf31161014b578063b4a0bdf3146106fc578063be26317e1461070d578063c0891ba914610717578063c29982381461072a57600080fd5b8063afcff50f146106ad578063b0772d0b146106d4578063b2068e84146106dc57600080fd5b8063929fe9a1116101ad578063929fe9a11461063357806394543c1514610674578063a843108114610687578063abfceffc1461069a57600080fd5b80638e6470ea146105bd5780638e8f294b146105d0578063921363951461062057600080fd5b8063528a174c116102ad57806361252fd11161024b57806379ba50971161022557806379ba50971461057e5780637dc0d1d01461058657806380d45a2d146105995780638da5cb5b146105ac57600080fd5b806361252fd11461054e5780636d0be88d14610563578063715018a61461057657600080fd5b806356aaee2d1161028757806356aaee2d146105025780635c21b6c5146105155780635cc4fdeb146105285780635ec88c791461053b57600080fd5b8063528a174c146104b157806352d84d1e146104c4578063530e784f146104ef57600080fd5b806324aaa2201161031a5780634a584432116102f45780634a584432146104475780634ada90af146104675780634e79238f14610470578063520b6c741461049e57600080fd5b806324aaa220146103f55780632bce219c146104085780633d98a1e51461041b57600080fd5b80627e3dd21461036157806302c3bcbb146103795780630e32cb86146103a757806312348e96146103bc578063186db48f146103cf5780631bc41f28146103e2575b600080fd5b60015b60405190151581526020015b60405180910390f35b6103996103873660046149bc565b60d16020526000908152604090205481565b604051908152602001610370565b6103ba6103b53660046149bc565b610853565b005b6103ba6103ca3660046149d9565b610867565b6103ba6103dd366004614a3e565b6109cd565b6103ba6103f0366004614aaa565b610b46565b6103ba610403366004614b14565b610f15565b6103ba610416366004614b98565b610fe2565b6103646104293660046149bc565b6001600160a01b0316600090815260cd602052604090205460ff1690565b6103996104553660046149bc565b60cf6020526000908152604090205481565b61039960cb5481565b61048361047e366004614c20565b6113c9565b60408051938452602084019290925290820152606001610370565b6103ba6104ac3660046149d9565b6113fa565b6104836104bf3660046149bc565b611458565b6104d76104d23660046149d9565b611483565b6040516001600160a01b039091168152602001610370565b6103ba6104fd3660046149bc565b6114ad565b6103ba6105103660046149bc565b611511565b6103ba6105233660046149bc565b611847565b6103ba610536366004614c66565b611973565b6104836105493660046149bc565b611bb0565b610556611bc2565b6040516103709190614c9b565b6103ba610571366004614ce8565b611c24565b6103ba611d9a565b6103ba611dae565b60c9546104d7906001600160a01b031681565b6103ba6105a73660046149d9565b611e25565b6033546001600160a01b03166104d7565b6103ba6105cb366004614d39565b611e36565b6106036105de3660046149bc565b60cd6020526000908152604090208054600182015460029092015460ff909116919083565b604080519315158452602084019290925290820152606001610370565b6103ba61062e3660046149bc565b611f4c565b610364610641366004614d7a565b6001600160a01b03808216600090815260cd60209081526040808320938616835260039093019052205460ff1692915050565b6103646106823660046149bc565b612332565b6103ba6106953660046149d9565b6123db565b6105566106a83660046149bc565b6124c9565b6104d77f000000000000000000000000000000000000000000000000000000000000000081565b61055661253f565b6106ef6106ea3660046149bc565b61259f565b6040516103709190614db3565b6097546001600160a01b03166104d7565b6103996101075481565b6103ba610725366004614d39565b6127e2565b61073d610738366004614e2b565b612a72565b6040516103709190614ef0565b61075d610758366004614d39565b612b29565b60408051928352602083019190915201610370565b6103ba6107803660046149bc565b612c54565b6103ba610793366004614a3e565b612e88565b6103ba6107a6366004614f28565b613045565b61039960d05481565b6104d76107c2366004614f4d565b613166565b6103ba6107d5366004614d39565b61319e565b6065546001600160a01b03166104d7565b6103646107f9366004614f88565b61355b565b61039960ca5481565b6103ba610815366004614fbd565b6135b2565b6103ba610828366004614d7a565b6137a2565b61039961083b3660046149bc565b6139dc565b6103ba61084e3660046149bc565b613c4e565b61085b613cbf565b61086481613d19565b50565b6108a56040518060400160405280601781526020017f736574436c6f7365466163746f722875696e7432353629000000000000000000815250613dd0565b80670c7d713b49da000010156109195760405162461bcd60e51b815260206004820152602e60248201527f436c6f736520666163746f722067726561746572207468616e206d6178696d7560448201526d369031b637b9b2903330b1ba37b960911b60648201526084015b60405180910390fd5b8066b1a2bc2ec5000011156109875760405162461bcd60e51b815260206004820152602e60248201527f436c6f736520666163746f7220736d616c6c6572207468616e206d696e696d7560448201526d369031b637b9b2903330b1ba37b960911b6064820152608401610910565b60ca80549082905560408051828152602081018490527f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd991015b60405180910390a15050565b6109ee60405180606001604052806028815260200161532160289139613dd0565b828181158015906109fe57508082145b610a3a5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b6044820152606401610910565b610a4382613e6e565b60005b82811015610b3d57848482818110610a6057610a60615017565b9050602002013560cf6000898985818110610a7d57610a7d615017565b9050602002016020810190610a9291906149bc565b6001600160a01b03168152602081019190915260400160002055868682818110610abe57610abe615017565b9050602002016020810190610ad391906149bc565b6001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110610b0f57610b0f615017565b90506020020135604051610b2591815260200190565b60405180910390a2610b3681615043565b9050610a46565b50505050505050565b610b51846004613ea1565b6001600160a01b038416600090815260cd60205260409020805460ff16610b9657604051635a9a1eb960e11b81526001600160a01b0386166004820152602401610910565b306001600160a01b03851603610c3e57306001600160a01b0316856001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c12919061505c565b6001600160a01b031614610c3957604051630c73eb0560e01b815260040160405180910390fd5b610d76565b6001600160a01b038416600090815260cd602052604090205460ff16610c8257604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b836001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce4919061505c565b6001600160a01b0316856001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f919061505c565b6001600160a01b031614610d7657604051630c73eb0560e01b815260040160405180910390fd5b6001600160a01b038216600090815260038201602052604090205460ff16610db5578482604051630cdfb2db60e31b8152600401610910929190615079565b60d35460005b81811015610b3d57600060d38281548110610dd857610dd8615017565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b038a8116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015610e2b57600080fd5b505af1158015610e3f573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150610e71908b908990600401615079565b600060405180830381600087803b158015610e8b57600080fd5b505af1158015610e9f573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150610ed1908b908a90600401615079565b600060405180830381600087803b158015610eeb57600080fd5b505af1158015610eff573d6000803e3d6000fd5b505050505080610f0e90615043565b9050610dbb565b610f366040518060600160405280602a815260200161539a602a9139613dd0565b8382610f4a610f458284615093565b613e6e565b60005b82811015610fd85760005b82811015610fc757610fb7898984818110610f7557610f75615017565b9050602002016020810190610f8a91906149bc565b888884818110610f9c57610f9c615017565b9050602002016020810190610fb191906150b2565b87613ecd565b610fc081615043565b9050610f58565b50610fd181615043565b9050610f4d565b5050505050505050565b6000610ff084613fdb61400f565b905060d054816000015111156110275760d0548151604051631a451c0f60e21b815260048101929092526024820152604401610910565b6000611047604051806020016040528060cb54815250836040015161405e565b82519091508110611078578151604051632c1f8ef160e21b8152610910918391600401918252602082015260400190565b8160a0015160000361109d5760405163095bf33360e01b815260040160405180910390fd5b826110ac610f456002836150cd565b60005b818110156112a45760cd60008787848181106110cd576110cd615017565b90506060020160200160208101906110e591906149bc565b6001600160a01b0316815260208101919091526040016000205460ff166111555785858281811061111857611118615017565b905060600201602001602081019061113091906149bc565b604051635a9a1eb960e11b81526001600160a01b039091166004820152602401610910565b60cd600087878481811061116b5761116b615017565b61118192602060609092020190810191506149bc565b6001600160a01b0316815260208101919091526040016000205460ff166111ca578585828181106111b4576111b4615017565b61113092602060609092020190810191506149bc565b368686838181106111dd576111dd615017565b90506060020190508060200160208101906111f891906149bc565b6001600160a01b0316638bbdb6db338a604085013561121a60208701876149bc565b60405160e086901b6001600160e01b03191681526001600160a01b0394851660048201529284166024840152604483019190915290911660648201526001608482015260a401600060405180830381600087803b15801561127a57600080fd5b505af115801561128e573d6000803e3d6000fd5b50505050508061129d90615043565b90506110af565b506001600160a01b038616600090815260cc602090815260408083208054825181850281018501909352808352919290919083018282801561130f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112f1575b505083519394506000925050505b818110156113be57600061134a84838151811061133c5761133c615017565b60200260200101518b61407e565b5091505080156113ad5760405162461bcd60e51b815260206004820152602860248201527f4e6f6e7a65726f20626f72726f772062616c616e6365206166746572206c69716044820152673ab4b230ba34b7b760c11b6064820152608401610910565b506113b781615043565b905061131d565b505050505050505050565b6000806000806113de88888888614125614159565b608081015160a09091015160009a919950975095505050505050565b61141b60405180606001604052806025815260200161534960259139613dd0565b60d080549082905560408051828152602081018490527eb4f4f153ad7f1397564a8830fef092481e8cf6a2cd3ff04f96d10ba51200a591016109c1565b60008060008061146a8561412561400f565b608081015160a090910151600097919650945092505050565b60ce818154811061149357600080fd5b6000918252602090912001546001600160a01b0316905081565b6114b5613cbf565b6114be8161438e565b60c980546001600160a01b038381166001600160a01b03198316179092556040519116907fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22906109c19083908590615079565b611519613cbf565b6001600160a01b038116600090815260d4602052604090205460ff16156115735760405162461bcd60e51b815260206004820152600e60248201526d616c72656164792065786973747360901b6044820152606401610910565b60d35460005b818110156116f157600060d3828154811061159657611596615017565b600091825260209182902001546040805163f7c618c160e01b815290516001600160a01b039092169263f7c618c1926004808401938290030181865afa1580156115e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611608919061505c565b9050836001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611648573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166c919061505c565b6001600160a01b0316816001600160a01b0316036116e05760405162461bcd60e51b815260206004820152602b60248201527f6469737472696275746f7220616c72656164792065786973747320776974682060448201526a1d1a1a5cc81c995dd85c9960aa1b6064820152608401610910565b506116ea81615043565b9050611579565b5060d354611703610f458260016150ef565b60d3805460018082019092557f915c3eb987b20e1af620c1403197bf687fb7f18513b3a73fde6e78c7072c41a60180546001600160a01b0319166001600160a01b038616908117909155600090815260d460205260408120805460ff191690921790915560ce54905b8181101561180c57846001600160a01b0316632a869a4d60ce838154811061179657611796615017565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401600060405180830381600087803b1580156117e357600080fd5b505af11580156117f7573d6000803e3d6000fd5b505050508061180590615043565b905061176c565b506040516001600160a01b038516907f058fa9577dc29aece41d41c2d3bff2ed4e8d5085762198e8f7faab35039555da90600090a250505050565b6001600160a01b038116600090815260cc60209081526040808320805482518185028101850190935280835291929091908301828280156118b157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611893575b5050835160c954949550936001600160a01b0316925060009150505b8281101561196c57816001600160a01b03166396e85ced8583815181106118f6576118f6615017565b60200260200101516040518263ffffffff1660e01b815260040161192991906001600160a01b0391909116815260200190565b600060405180830381600087803b15801561194357600080fd5b505af1158015611957573d6000803e3d6000fd5b505050508061196590615043565b90506118cd565b5050505050565b6119946040518060600160405280602c815260200161536e602c9139613dd0565b6001600160a01b038316600090815260cd60205260409020805460ff166119d957604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b670c7d713b49da0000831115611a02576040516302f22cad60e61b815260040160405180910390fd5b670de0b6b3a7640000821115611a2a5760405162f9474b60e61b815260040160405180910390fd5b82821015611a4a5760405162f9474b60e61b815260040160405180910390fd5b8215801590611ac4575060c95460405163fc57d4df60e01b81526001600160a01b0386811660048301529091169063fc57d4df90602401602060405180830381865afa158015611a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac29190615107565b155b15611aec5760405162e52a7d60e41b81526001600160a01b0385166004820152602401610910565b6001810154838114611b4a5760018201849055604080516001600160a01b0387168152602081018390529081018590527f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59060600160405180910390a15b6002820154838114611ba85760028301849055604080516001600160a01b0388168152602081018390529081018590527f9e92c7d5fef69846094f3ddcadcb9402c6ba469c461368714f1cabd8ef48b5919060600160405180910390a15b505050505050565b60008060008061146a85613fdb61400f565b606060d3805480602002602001604051908101604052809291908181526020018280548015611c1a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611bfc575b5050505050905090565b611c2f846006613ea1565b611c3a8484836143b5565b60d35460005b81811015611ba857600060d38281548110611c5d57611c5d615017565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03898116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015611cb057600080fd5b505af1158015611cc4573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611cf6908a908a90600401615079565b600060405180830381600087803b158015611d1057600080fd5b505af1158015611d24573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611d56908a908990600401615079565b600060405180830381600087803b158015611d7057600080fd5b505af1158015611d84573d6000803e3d6000fd5b505050505080611d9390615043565b9050611c40565b611da2613cbf565b611dac6000614463565b565b60655433906001600160a01b03168114611e1c5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610910565b61086481614463565b611e2d613cbf565b6108648161447c565b611e41836001613ea1565b611e4c8383836143b5565b60d35460005b8181101561196c57600060d38281548110611e6f57611e6f615017565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03888116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015611ec257600080fd5b505af1158015611ed6573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611f089089908990600401615079565b600060405180830381600087803b158015611f2257600080fd5b505af1158015611f36573d6000803e3d6000fd5b505050505080611f4590615043565b9050611e52565b6001600160a01b038116600090815260cc6020908152604080832080548251818502810185019093528083529192909190830182828015611fb657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611f98575b5050835160c954949550933393506001600160a01b03169150600090505b838110156120f157848181518110611fee57611fee615017565b60200260200101516001600160a01b031663a6afed956040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120599190615107565b50816001600160a01b03166396e85ced86838151811061207b5761207b615017565b60200260200101516040518263ffffffff1660e01b81526004016120ae91906001600160a01b0391909116815260200190565b600060405180830381600087803b1580156120c857600080fd5b505af11580156120dc573d6000803e3d6000fd5b50505050806120ea90615043565b9050611fd4565b5050600061210185613fdb61400f565b905060d054816000015111156121385760d0548151604051631a451c0f60e21b815260048101929092526024820152604401610910565b8060a0015160000361215d5760405163095bf33360e01b815260040160405180910390fd5b60408051602080820183528351825282518082018452848401518152835191820190935260cb54815290916000916121959190614518565b905060006121a38383614560565b90506121c76040518060200160405280670de0b6b3a7640000815250825190511090565b156121f25781518351604051631a451c0f60e21b815260048101929092526024820152604401610910565b60005b868110156113be57600088828151811061221157612211615017565b60200260200101519050600080612228838d61407e565b50915091506000612239868361405e565b905082156122ac5760405163b2a02ff160e01b81526001600160a01b038b811660048301528e811660248301526044820185905285169063b2a02ff190606401600060405180830381600087803b15801561229357600080fd5b505af11580156122a7573d6000803e3d6000fd5b505050505b811561231d5760405163227f37ff60e11b81526001600160a01b038b811660048301528e81166024830152604482018390528516906344fe6ffe90606401600060405180830381600087803b15801561230457600080fd5b505af1158015612318573d6000803e3d6000fd5b505050505b505050508061232b90615043565b90506121f5565b6001600160a01b038116600090815260cd6020526040812060010154158015612361575061236182600261355b565b80156123d55750670de0b6b3a7640000826001600160a01b031663173b99046040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d39190615107565b145b92915050565b670de0b6b3a764000081101561244d5760405162461bcd60e51b815260206004820152603160248201527f6c69717569646174696f6e20696e63656e746976652073686f756c64206265206044820152700cee4cac2e8cae440e8d0c2dc4062ca627607b1b6064820152608401610910565b61248b6040518060400160405280602081526020017f7365744c69717569646174696f6e496e63656e746976652875696e7432353629815250613dd0565b60cb80549082905560408051828152602081018490527faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec131691016109c1565b6001600160a01b038116600090815260cc6020908152604080832080548251818502810185019093528083526060949383018282801561253257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612514575b5093979650505050505050565b606060ce805480602002602001604051908101604052809291908181526020018280548015611c1a576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311611bfc575050505050905090565b60d3546060908067ffffffffffffffff8111156125be576125be614e15565b60405190808252806020026020018201604052801561261c57816020015b612609604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b8152602001906001900390816125dc5790505b50915060005b818110156127db57600060d3828154811061263f5761263f615017565b60009182526020808320909101546040805163f7c618c160e01b815290516001600160a01b039092169450849263f7c618c1926004808401938290030181865afa158015612691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b5919061505c565b604080516060810182526001600160a01b0380841682529151631d31307360e21b815289831660048201529293509160208301918516906374c4c1cc90602401602060405180830381865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127369190615107565b8152604051637c05a7c560e01b81526001600160a01b038981166004830152602090920191851690637c05a7c590602401602060405180830381865afa158015612784573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a89190615107565b8152508584815181106127bd576127bd615017565b60200260200101819052505050806127d490615043565b9050612622565b5050919050565b6127ed836000613ea1565b6001600160a01b038316600090815260cd602052604090205460ff1661283157604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b038316600090815260d160205260409020546000198114612972576000846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b79190615107565b905060006040518060200160405280876001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612904573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129289190615107565b90529050600061293982848761459a565b90508381111561296e5760405163db33be3d60e01b81526001600160a01b038816600482015260248101859052604401610910565b5050505b60d35460005b81811015611ba857600060d3828154811061299557612995615017565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03898116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b1580156129e857600080fd5b505af11580156129fc573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150612a2e908a908a90600401615079565b600060405180830381600087803b158015612a4857600080fd5b505af1158015612a5c573d6000803e3d6000fd5b505050505080612a6b90615043565b9050612978565b805160609060008167ffffffffffffffff811115612a9257612a92614e15565b604051908082528060200260200182016040528015612abb578160200160208202803683370190505b50905060005b82811015612b21576000858281518110612add57612add615017565b60200260200101519050612af181336145c4565b6000838381518110612b0557612b05615017565b602090810291909101015250612b1a81615043565b9050612ac1565b509392505050565b6000806000612b37866146c0565b90506000612b44866146c0565b90506000866001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612baa9190615107565b90506000612bc46040518060200160405280600081525090565b60408051602080820183526000808352835180830185529081528351808301855260cb54815284519283019094528882529192612c0091614518565b9250612c28604051806020016040528088815250604051806020016040528088815250614518565b9150612c348383614560565b9050612c40818b61405e565b60009d909c509a5050505050505050505050565b612c7d7f000000000000000000000000000000000000000000000000000000000000000061475f565b6001600160a01b038116600090815260cd602052604090205460ff1615612cc25760405163d005ce4760e01b81526001600160a01b0382166004820152602401610910565b806001600160a01b0316633d9ea3a16040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d249190615120565b612d705760405162461bcd60e51b815260206004820152601b60248201527f436f6d7074726f6c6c65723a20496e76616c69642076546f6b656e00000000006044820152606401610910565b6001600160a01b038116600090815260cd60205260408120805460ff19166001908117825581018290556002810191909155612dab8261478c565b60d35460005b81811015612e455760d38181548110612dcc57612dcc615017565b600091825260209091200154604051632a869a4d60e01b81526001600160a01b03868116600483015290911690632a869a4d90602401600060405180830381600087803b158015612e1c57600080fd5b505af1158015612e30573d6000803e3d6000fd5b5050505080612e3e90615043565b9050612db1565b506040516001600160a01b03841681527faf16ad15f9e29d5140e8e81a30a92a755aa8edff3d301053c84392b70c0d09a3906020015b60405180910390a1505050565b612ea96040518060600160405280602881526020016153c460289139613dd0565b826000819003612ef75760405162461bcd60e51b8152602060048201526019602482015278696e76616c6964206e756d626572206f66206d61726b65747360381b6044820152606401610910565b808214612f425760405162461bcd60e51b8152602060048201526019602482015278696e76616c6964206e756d626572206f66206d61726b65747360381b6044820152606401610910565b612f4b81613e6e565b60005b81811015611ba857838382818110612f6857612f68615017565b9050602002013560d16000888885818110612f8557612f85615017565b9050602002016020810190612f9a91906149bc565b6001600160a01b03168152602081019190915260400160002055858582818110612fc657612fc6615017565b9050602002016020810190612fdb91906149bc565b6001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f885858481811061301757613017615017565b9050602002013560405161302d91815260200190565b60405180910390a261303e81615043565b9050612f4e565b600054610100900460ff16158080156130655750600054600160ff909116105b8061307f5750303b15801561307f575060005460ff166001145b6130e25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610910565b6000805460ff191660011790558015613105576000805461ff0019166101001790555b61310d61485b565b6131168261488a565b61311f8361447c565b8015613161576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001612e7b565b505050565b60cc602052816000526040600020818154811061318257600080fd5b6000918252602090912001546001600160a01b03169150829050565b6131a9836002613ea1565b6001600160a01b038316600090815260cd602052604090205460ff166131ed57604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b03808416600090815260cd60209081526040808320938616835260039093019052205460ff16613231576132278361475f565b61323133836145c4565b61323a82611847565b60c95460405163fc57d4df60e01b81526001600160a01b0385811660048301529091169063fc57d4df90602401602060405180830381865afa158015613284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a89190615107565b6000036132d25760405162e52a7d60e41b81526001600160a01b0384166004820152602401610910565b6001600160a01b038316600090815260cf6020526040902054600019811461339e576000846001600160a01b03166347bd37186040518163ffffffff1660e01b8152600401602060405180830381865afa158015613334573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133589190615107565b9050600061336684836150ef565b90508281111561339b57604051632e649eed60e01b81526001600160a01b038716600482015260248101849052604401610910565b50505b60006133b08486600086614125614159565b60a0810151909150156133d65760405163bb55fd2760e01b815260040160405180910390fd5b60006040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134459190615107565b905260d35490915060005b81811015610fd857600060d3828154811061346d5761346d615017565b600091825260209091200154604051632352607960e01b81526001600160a01b038b811660048301528651602483015290911691508190632352607990604401600060405180830381600087803b1580156134c757600080fd5b505af11580156134db573d6000803e3d6000fd5b5050604051636a95ddef60e01b81526001600160a01b038c811660048301528b811660248301528751604483015284169250636a95ddef9150606401600060405180830381600087803b15801561353157600080fd5b505af1158015613545573d6000803e3d6000fd5b50505050508061355490615043565b9050613450565b6001600160a01b038216600090815260d260205260408120818360088111156135865761358661513d565b60088111156135975761359761513d565b815260208101919091526040016000205460ff169392505050565b6135bd856005613ea1565b6135c683611847565b6001600160a01b038516600090815260cd602052604090205460ff1661360a57604051635a9a1eb960e11b81526001600160a01b0386166004820152602401610910565b6001600160a01b038416600090815260cd602052604090205460ff1661364e57604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b6040516395dd919360e01b81526001600160a01b038481166004830152600091908716906395dd919390602401602060405180830381865afa158015613698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136bc9190615107565b905081806136ce57506136ce86612332565b156136fa57808311156136f45760405163e46c155960e01b815260040160405180910390fd5b5061196c565b600061370885613fdb61400f565b905060d05481600001511161373e5760d0548151604051636e61bb0560e11b815260048101929092526024820152604401610910565b8060a001516000036137635760405163095bf33360e01b815260040160405180910390fd5b600061377f604051806020016040528060ca548152508461405e565b905080851115610fd85760405163e46c155960e01b815260040160405180910390fd5b6137ad826003613ea1565b60c9546040516396e85ced60e01b81526001600160a01b038481166004830152909116906396e85ced90602401600060405180830381600087803b1580156137f457600080fd5b505af1158015613808573d6000803e3d6000fd5b505050506001600160a01b038216600090815260cd602052604090205460ff1661385057604051635a9a1eb960e11b81526001600160a01b0383166004820152602401610910565b60d35460005b818110156139d65760006040518060200160405280866001600160a01b031663aa5af0fd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138cd9190615107565b8152509050600060d383815481106138e7576138e7615017565b600091825260209091200154604051632352607960e01b81526001600160a01b0388811660048301528451602483015290911691508190632352607990604401600060405180830381600087803b15801561394157600080fd5b505af1158015613955573d6000803e3d6000fd5b5050604051636a95ddef60e01b81526001600160a01b03898116600483015288811660248301528551604483015284169250636a95ddef9150606401600060405180830381600087803b1580156139ab57600080fd5b505af11580156139bf573d6000803e3d6000fd5b505050505050806139cf90615043565b9050613856565b50505050565b60006139e9826008613ea1565b816000806139f7833361407e565b509150915080600014613a1d5760405163f8a5d66d60e01b815260040160405180910390fd5b613a288533846143b5565b6001600160a01b038316600090815260cd60209081526040808320338452600381019092529091205460ff16613a645750600095945050505050565b3360009081526003820160209081526040808320805460ff1916905560cc825280832080548251818502810185019093528083529192909190830182828015613ad657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613ab8575b5050835193945083925060009150505b82811015613b3857876001600160a01b0316848281518110613b0a57613b0a615017565b60200260200101516001600160a01b031603613b2857809150613b38565b613b3181615043565b9050613ae6565b50818110613b4857613b48615153565b33600090815260cc6020526040902080548190613b6790600190615169565b81548110613b7757613b77615017565b9060005260206000200160009054906101000a90046001600160a01b0316818381548110613ba757613ba7615017565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080805480613be557613be5615180565b600082815260208120820160001990810180546001600160a01b031916905590910190915560405133916001600160a01b038b16917fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d9190a35060009998505050505050505050565b613c56613cbf565b606580546001600160a01b0383166001600160a01b03199091168117909155613c876033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b03163314611dac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610910565b6001600160a01b038116613d7d5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b6064820152608401610910565b609780546001600160a01b038381166001600160a01b03198316179092556040519116907f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0906109c19083908590615079565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab90613e0390339086906004016151e3565b602060405180830381865afa158015613e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e449190615120565b905080613e6a57333083604051634a3fa29360e01b815260040161091093929190615207565b5050565b61010754811115610864576101075460405163792bfb1b60e11b8152600481019190915260248101829052604401610910565b613eab828261355b565b15613e6a5781816040516313b3ccb160e31b8152600401610910929190615255565b6001600160a01b038316600090815260cd602052604090205460ff16613f465760405162461bcd60e51b815260206004820152602860248201527f63616e6e6f742070617573652061206d61726b65742074686174206973206e6f6044820152671d081b1a5cdd195960c21b6064820152608401610910565b6001600160a01b038316600090815260d2602052604081208291846008811115613f7257613f7261513d565b6008811115613f8357613f8361513d565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d838383604051612e7b93929190615272565b6040805160208082018352600091829052825180820184526001600160a01b0394909416825260cd90522060020154815290565b6140486040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61405783600080600086614159565b9392505050565b60008061406b84846148b1565b9050614076816148d9565b949350505050565b6040516361bfb47160e11b81526001600160a01b03828116600483015260009182918291829187169063c37f68e290602401608060405180830381865afa1580156140cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140f1919061529f565b919650945092509050801561411d57858560405163015e34d960e61b8152600401610910929190615079565b509250925092565b6040805160208082018352600091829052825180820184526001600160a01b0394909416825260cd90522060010154815290565b6141926040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6001600160a01b038616600090815260cc60209081526040808320805482518185028101850190935280835291929091908301828280156141fc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116141de575b505083519394506000925050505b8181101561433057600083828151811061422657614226615017565b60200260200101519050600080600061423f848e61407e565b9250925092506000604051806020016040528061425b876146c0565b8152509050600061427a60405180602001604052808581525083614518565b9050600061429461428e888e63ffffffff16565b83614518565b90506142a581878d6020015161459a565b60208c01528a516142b9908390889061459a565b8b5260408b01516142cd908490879061459a565b8b60400181815250508e6001600160a01b0316876001600160a01b031603614318576142fe818f8d6060015161459a565b60608c018190526143129084908f9061459a565b60608c01525b505050505050508061432990615043565b905061420a565b5060008360600151846040015161434791906150ef565b9050808460200151111561436e5760208401518190036080850152600060a0850152614382565b600060808501526020840151810360a08501525b50505095945050505050565b6001600160a01b038116610864576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b038316600090815260cd60205260409020805460ff166143fa57604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b6001600160a01b038316600090815260038201602052604090205460ff166144225750505050565b61442b83611847565b600061443d8486856000614125614159565b60a08101519091501561196c5760405163bb55fd2760e01b815260040160405180910390fd5b606580546001600160a01b0319169055610864816148f1565b6101075481116144d95760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b6064820152608401610910565b61010780549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa91016109c1565b6040805160208101909152600081526040518060200160405280670de0b6b3a764000061454d86600001518660000151614943565b61455791906150cd565b90529392505050565b60408051602081019091526000815260405180602001604052806145576145938660000151670de0b6b3a7640000614943565b855161494f565b6000806145a785856148b1565b90506145bb6145b5826148d9565b8461495b565b95945050505050565b6145cf826007613ea1565b6001600160a01b038216600090815260cd60205260409020805460ff1661461457604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b038216600090815260038201602052604090205460ff161561463c57505050565b6001600160a01b0380831660008181526003840160209081526040808320805460ff1916600190811790915560cc835281842080549182018155845291832090910180549488166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a3505050565b60c95460405163fc57d4df60e01b81526001600160a01b038381166004830152600092839291169063fc57d4df90602401602060405180830381865afa15801561470e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147329190615107565b9050806000036123d55760405162e52a7d60e41b81526001600160a01b0384166004820152602401610910565b336001600160a01b03821614610864578033604051634e9383fb60e11b8152600401610910929190615079565b60ce5460005b8181101561480557826001600160a01b031660ce82815481106147b7576147b7615017565b6000918252602090912001546001600160a01b0316036147f55760405163d005ce4760e01b81526001600160a01b0384166004820152602401610910565b6147fe81615043565b9050614792565b505060ce805460018101825560008290527fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a0180546001600160a01b0319166001600160a01b03841617905554613e6a81613e6e565b600054610100900460ff166148825760405162461bcd60e51b8152600401610910906152d5565b611dac614967565b600054610100900460ff1661085b5760405162461bcd60e51b8152600401610910906152d5565b6040805160208101909152600081526040518060200160405280614557856000015185614943565b80516000906123d590670de0b6b3a7640000906150cd565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006140578284615093565b600061405782846150cd565b600061405782846150ef565b600054610100900460ff1661498e5760405162461bcd60e51b8152600401610910906152d5565b611dac33614463565b6001600160a01b038116811461086457600080fd5b80356149b781614997565b919050565b6000602082840312156149ce57600080fd5b813561405781614997565b6000602082840312156149eb57600080fd5b5035919050565b60008083601f840112614a0457600080fd5b50813567ffffffffffffffff811115614a1c57600080fd5b6020830191508360208260051b8501011115614a3757600080fd5b9250929050565b60008060008060408587031215614a5457600080fd5b843567ffffffffffffffff80821115614a6c57600080fd5b614a78888389016149f2565b90965094506020870135915080821115614a9157600080fd5b50614a9e878288016149f2565b95989497509550505050565b60008060008060808587031215614ac057600080fd5b8435614acb81614997565b93506020850135614adb81614997565b92506040850135614aeb81614997565b91506060850135614afb81614997565b939692955090935050565b801515811461086457600080fd5b600080600080600060608688031215614b2c57600080fd5b853567ffffffffffffffff80821115614b4457600080fd5b614b5089838a016149f2565b90975095506020880135915080821115614b6957600080fd5b50614b76888289016149f2565b9094509250506040860135614b8a81614b06565b809150509295509295909350565b600080600060408486031215614bad57600080fd5b8335614bb881614997565b9250602084013567ffffffffffffffff80821115614bd557600080fd5b818601915086601f830112614be957600080fd5b813581811115614bf857600080fd5b876020606083028501011115614c0d57600080fd5b6020830194508093505050509250925092565b60008060008060808587031215614c3657600080fd5b8435614c4181614997565b93506020850135614c5181614997565b93969395505050506040820135916060013590565b600080600060608486031215614c7b57600080fd5b8335614c8681614997565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015614cdc5783516001600160a01b031683529284019291840191600101614cb7565b50909695505050505050565b60008060008060808587031215614cfe57600080fd5b8435614d0981614997565b93506020850135614d1981614997565b92506040850135614d2981614997565b9396929550929360600135925050565b600080600060608486031215614d4e57600080fd5b8335614d5981614997565b92506020840135614d6981614997565b929592945050506040919091013590565b60008060408385031215614d8d57600080fd5b8235614d9881614997565b91506020830135614da881614997565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015614e0857815180516001600160a01b0316855286810151878601528501518585015260609093019290850190600101614dd0565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215614e3e57600080fd5b823567ffffffffffffffff80821115614e5657600080fd5b818501915085601f830112614e6a57600080fd5b813581811115614e7c57614e7c614e15565b8060051b604051601f19603f83011681018181108582111715614ea157614ea1614e15565b604052918252848201925083810185019188831115614ebf57600080fd5b938501935b82851015614ee457614ed5856149ac565b84529385019392850192614ec4565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614cdc57835183529284019291840191600101614f0c565b60008060408385031215614f3b57600080fd5b823591506020830135614da881614997565b60008060408385031215614f6057600080fd5b8235614f6b81614997565b946020939093013593505050565b8035600981106149b757600080fd5b60008060408385031215614f9b57600080fd5b8235614fa681614997565b9150614fb460208401614f79565b90509250929050565b600080600080600060a08688031215614fd557600080fd5b8535614fe081614997565b94506020860135614ff081614997565b9350604086013561500081614997565b9250606086013591506080860135614b8a81614b06565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016150555761505561502d565b5060010190565b60006020828403121561506e57600080fd5b815161405781614997565b6001600160a01b0392831681529116602082015260400190565b60008160001904831182151516156150ad576150ad61502d565b500290565b6000602082840312156150c457600080fd5b61405782614f79565b6000826150ea57634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156151025761510261502d565b500190565b60006020828403121561511957600080fd5b5051919050565b60006020828403121561513257600080fd5b815161405781614b06565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b60008282101561517b5761517b61502d565b500390565b634e487b7160e01b600052603160045260246000fd5b6000815180845260005b818110156151bc576020818501810151868301820152016151a0565b818111156151ce576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038316815260406020820181905260009061407690830184615196565b6001600160a01b038481168252831660208201526060604082018190526000906145bb90830184615196565b6009811061525157634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b0383168152604081016140576020830184615233565b6001600160a01b03841681526060810161528f6020830185615233565b8215156040830152949350505050565b600080600080608085870312156152b557600080fd5b505082516020840151604085015160609095015191969095509092509050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d297365744d696e4c6971756964617461626c65436f6c6c61746572616c2875696e7432353629736574436f6c6c61746572616c466163746f7228616464726573732c75696e743235362c75696e7432353629736574416374696f6e7350617573656428616464726573735b5d2c75696e743235365b5d2c626f6f6c297365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d29a26469706673582212202bcb0fe3478fc86c1351748222cd27e55828f204dabec416b9e29c89f475b53d64736f6c634300080d0033", + "solcInputHash": "8e6073e680dfb04e9a49d04e0bdfc250", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"ActionPaused\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"cap\",\"type\":\"uint256\"}],\"name\":\"BorrowCapExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedLessThanOrEqualTo\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"CollateralExceedsThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ComptrollerMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"collateralToSeize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCollateral\",\"type\":\"uint256\"}],\"name\":\"InsufficientCollateral\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientShortfall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCollateralFactor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLiquidationThreshold\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"}],\"name\":\"MarketAlreadyListed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"MarketNotCollateral\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"}],\"name\":\"MarketNotListed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopsLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredLoops\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedGreaterThan\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"MinimalCollateralViolated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonzeroBorrowBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"PriceError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"SnapshotError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"cap\",\"type\":\"uint256\"}],\"name\":\"SupplyCapExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooMuchRepay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"calledContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"methodSignature\",\"type\":\"string\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"expectedSender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"actualSender\",\"type\":\"address\"}],\"name\":\"UnexpectedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"pauseState\",\"type\":\"bool\"}],\"name\":\"ActionPausedMarket\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketExited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketSupported\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMaxLoopsLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newmaxLoopsLimit\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBorrowCap\",\"type\":\"uint256\"}],\"name\":\"NewBorrowCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCloseFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCloseFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCollateralFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCollateralFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldLiquidationIncentiveMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"NewLiquidationIncentive\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldLiquidationThresholdMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLiquidationThresholdMantissa\",\"type\":\"uint256\"}],\"name\":\"NewLiquidationThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMinLiquidatableCollateral\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMinLiquidatableCollateral\",\"type\":\"uint256\"}],\"name\":\"NewMinLiquidatableCollateral\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"oldPriceOracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"newPriceOracle\",\"type\":\"address\"}],\"name\":\"NewPriceOracle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardsDistributor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"}],\"name\":\"NewRewardsDistributor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSupplyCap\",\"type\":\"uint256\"}],\"name\":\"NewSupplyCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract RewardsDistributor\",\"name\":\"_rewardsDistributor\",\"type\":\"address\"}],\"name\":\"addRewardsDistributor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"checkMembership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"vTokens\",\"type\":\"address[]\"}],\"name\":\"enterMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenAddress\",\"type\":\"address\"}],\"name\":\"exitMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllMarkets\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAssetsIn\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getBorrowingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenModify\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"getHypotheticalAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRewardDistributors\",\"outputs\":[{\"internalType\":\"contract RewardsDistributor[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"getRewardsByMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"supplySpeed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowSpeed\",\"type\":\"uint256\"}],\"internalType\":\"struct ComptrollerStorage.RewardSpeeds[]\",\"name\":\"rewardSpeeds\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"healAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accessControlManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isComptroller\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"isDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"isMarketListed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract VToken\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ComptrollerStorage.LiquidationOrder[]\",\"name\":\"orders\",\"type\":\"tuple[]\"}],\"name\":\"liquidateAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateCalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokensToSeize\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidationThresholdMantissa\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLoopsLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minLiquidatableCollateral\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"preBorrowHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"skipLiquidityCheck\",\"type\":\"bool\"}],\"name\":\"preLiquidateHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"mintAmount\",\"type\":\"uint256\"}],\"name\":\"preMintHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"preRedeemHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"}],\"name\":\"preRepayHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"seizerContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"}],\"name\":\"preSeizeHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"preTransferHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"marketsList\",\"type\":\"address[]\"},{\"internalType\":\"enum ComptrollerStorage.Action[]\",\"name\":\"actionsList\",\"type\":\"uint8[]\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"setActionsPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"setCloseFactor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLiquidationThresholdMantissa\",\"type\":\"uint256\"}],\"name\":\"setCollateralFactor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"setLiquidationIncentive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newBorrowCaps\",\"type\":\"uint256[]\"}],\"name\":\"setMarketBorrowCaps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newSupplyCaps\",\"type\":\"uint256[]\"}],\"name\":\"setMarketSupplyCaps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setMaxLoopsLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newMinLiquidatableCollateral\",\"type\":\"uint256\"}],\"name\":\"setMinLiquidatableCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"setPriceOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"supportMarket\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action to check\",\"market\":\"vToken address\"},\"returns\":{\"_0\":\"paused True if the action is paused otherwise false\"}},\"addRewardsDistributor(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewRewardsDistributor with distributor address\",\"details\":\"Only callable by the admin\",\"params\":{\"_rewardsDistributor\":\"Address of the RewardDistributor contract to add\"}},\"checkMembership(address,address)\":{\"params\":{\"account\":\"The address of the account to check\",\"vToken\":\"The vToken to check\"},\"returns\":{\"_0\":\"True if the account is in the market specified, otherwise false.\"}},\"constructor\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"params\":{\"poolRegistry_\":\"Pool registry address\"}},\"enterMarkets(address[])\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if entering any of the markets is pausedMarketNotListed error is thrown if any of the markets is not listed\",\"custom:event\":\"MarketEntered is emitted for each market on success\",\"params\":{\"vTokens\":\"The list of addresses of the vToken markets to be enabled\"},\"returns\":{\"_0\":\"errors An array of NO_ERROR for compatibility with Venus core tooling\"}},\"exitMarket(address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if exiting the market is pausedNonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if exiting the market would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"custom:event\":\"MarketExited is emitted on success\",\"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\"},\"returns\":{\"_0\":\"error Always NO_ERROR for compatibility with Venus core tooling\"}},\"getAccountLiquidity(address)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"params\":{\"account\":\"The account get liquidity for\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Account liquidity in excess of liquidation threshold requirements,\",\"shortfall\":\"Account shortfall below liquidation threshold requirements\"}},\"getAllMarkets()\":{\"details\":\"The automatic getter may be used to access an individual market.\",\"returns\":{\"_0\":\"markets The list of market addresses\"}},\"getAssetsIn(address)\":{\"params\":{\"account\":\"The address of the account to pull assets for\"},\"returns\":{\"_0\":\"A list with the assets the account has entered\"}},\"getBorrowingPower(address)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"params\":{\"account\":\"The account get liquidity for\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Account liquidity in excess of collateral requirements,\",\"shortfall\":\"Account shortfall below collateral requirements\"}},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"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\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Hypothetical account liquidity in excess of collateral requirements,\",\"shortfall\":\"Hypothetical account shortfall below collateral requirements\"}},\"getRewardDistributors()\":{\"returns\":{\"_0\":\"Array of RewardDistributor addresses\"}},\"getRewardsByMarket(address)\":{\"params\":{\"vToken\":\"The vToken to get the reward speeds for\"},\"returns\":{\"rewardSpeeds\":\"Array of total supply and borrow speeds and reward token for all reward distributors\"}},\"healAccount(address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"CollateralExceedsThreshold error is thrown when the collateral is too big for healingSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"user\":\"account to heal\"}},\"initialize(uint256,address)\":{\"params\":{\"accessControlManager\":\"Access control manager contract address\",\"loopLimit\":\"Limit for the loops can iterate to avoid the DOS\"}},\"isComptroller()\":{\"returns\":{\"_0\":\"Always true\"}},\"isDeprecated(address)\":{\"details\":\"All borrows in a deprecated vToken market can be immediately liquidated\",\"params\":{\"vToken\":\"The market to check if deprecated\"},\"returns\":{\"_0\":\"deprecated True if the given vToken market has been deprecated\"}},\"isMarketListed(address)\":{\"params\":{\"vToken\":\"vToken Address for the market to check\"},\"returns\":{\"_0\":\"listed True if listed otherwise false\"}},\"liquidateAccount(address,(address,address,uint256)[])\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidationInsufficientCollateral error is thrown when there is not enough collateral to cover the debtSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"borrower\":\"the borrower address\",\"orders\":\"an array of liquidation orders\"}},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"custom:error\":\"PriceError if the oracle returns an invalid price\",\"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\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"tokensToSeize\":\"Number of vTokenCollateral tokens to be seized in a liquidation\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"preLiquidateHook(address,address,address,uint256,bool)\":{\"custom:error\":\"ActionPaused error is thrown if liquidations are paused in this marketMarketNotListed error is thrown if either collateral or borrowed token is not listedTooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factorMinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidationsInsufficientShortfall is thrown when trying to liquidate a healthy accountSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"borrower\":\"The address of the borrower\",\"repayAmount\":\"The amount of underlying being repaid\",\"skipLiquidityCheck\":\"Allows the borrow to be liquidated regardless of the account liquidity\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"preMintHook(address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if supplying to this market is pausedMarketNotListed error is thrown when the market is not listedSupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\",\"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\"}},\"preRedeemHook(address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if withdrawals are paused in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"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\"}},\"preRepayHook(address,address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if repayments are paused in this marketMarketNotListed error is thrown when the market is not listed\",\"params\":{\"borrower\":\"The account which would borrowed the asset\",\"vToken\":\"The market to verify the repay against\"}},\"preSeizeHook(address,address,address,address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if seizing this type of collateral is pausedMarketNotListed error is thrown if either collateral or borrowed token is not listedComptrollerMismatch error is when seizer contract or seized asset belong to different pools\",\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizerContract\":\"Contract that tries to seize the asset (either borrowed vToken or Comptroller)\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"preTransferHook(address,address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if withdrawals are paused in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"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\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewAccessControlManager event\",\"details\":\"Admin function to set address of AccessControlManager\",\"params\":{\"accessControlManager_\":\"The new address of the AccessControlManager\"}},\"setActionsPaused(address[],uint8[],bool)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"actionsList\":\"List of action ids to pause/unpause\",\"marketsList\":\"Markets to pause/unpause the actions on\",\"paused\":\"The new paused state (true=paused, false=unpaused)\"}},\"setCloseFactor(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:event\":\"Emits NewCloseFactor on success\",\"params\":{\"newCloseFactorMantissa\":\"New close factor, scaled by 1e18\"}},\"setCollateralFactor(address,uint256,uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:error\":\"MarketNotListed error is thrown when the market is not listedInvalidCollateralFactor error is thrown when collateral factor is too highInvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factorPriceError is thrown when the oracle returns an invalid price for the asset\",\"custom:event\":\"Emits NewCollateralFactor when collateral factor is updated and NewLiquidationThreshold when liquidation threshold is updated\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newCollateralFactorMantissa\":\"The new collateral factor, scaled by 1e18\",\"newLiquidationThresholdMantissa\":\"The new liquidation threshold, scaled by 1e18\",\"vToken\":\"The market to set the factor on\"}},\"setLiquidationIncentive(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:event\":\"Emits NewLiquidationIncentive on success\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newLiquidationIncentiveMantissa\":\"New liquidationIncentive scaled by 1e18\"}},\"setMarketBorrowCaps(address[],uint256[])\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManagerA borrow cap of type(uint256).max corresponds to unlimited borrowing.Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed until the total borrows amount goes below the new borrow cap\",\"params\":{\"newBorrowCaps\":\"The new borrow cap values in underlying to be set. A value of type(uint256).max corresponds to unlimited borrowing.\",\"vTokens\":\"The addresses of the markets (tokens) to change the borrow caps for\"}},\"setMarketSupplyCaps(address[],uint256[])\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManagerA supply cap of type(uint256).max corresponds to unlimited supply.Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed until the total supplies amount goes below the new supply cap\",\"params\":{\"newSupplyCaps\":\"The new supply cap values in underlying to be set. A value of type(uint256).max corresponds to unlimited supply.\",\"vTokens\":\"The addresses of the markets (tokens) to change the supply caps for\"}},\"setMaxLoopsLimit(uint256)\":{\"params\":{\"limit\":\"Limit for the max loops can execute at a time\"}},\"setMinLiquidatableCollateral(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newMinLiquidatableCollateral\":\"The new min liquidatable collateral (in USD).\"}},\"setPriceOracle(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when the new oracle address is zero\",\"custom:event\":\"Emits NewPriceOracle on success\",\"details\":\"Only callable by the admin\",\"params\":{\"newOracle\":\"Address of the new price oracle to set\"}},\"supportMarket(address)\":{\"custom:access\":\"Only PoolRegistry\",\"custom:error\":\"MarketAlreadyListed is thrown if the market is already listed in this pool\",\"details\":\"Only callable by the PoolRegistry\",\"params\":{\"vToken\":\"The address of the market (token) to list\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"updatePrices(address)\":{\"params\":{\"account\":\"Address of the account to get associated tokens with\"}}},\"stateVariables\":{\"poolRegistry\":{\"custom:oz-upgrades-unsafe-allow\":\"state-variable-immutable\"}},\"title\":\"Comptroller\",\"version\":1},\"userdoc\":{\"errors\":{\"ActionPaused(address,uint8)\":[{\"notice\":\"Thrown when trying to perform an action that is paused\"}],\"BorrowCapExceeded(address,uint256)\":[{\"notice\":\"Thrown if the borrow cap is exceeded\"}],\"ComptrollerMismatch()\":[{\"notice\":\"Thrown when a market has an unexpected comptroller\"}],\"InsufficientLiquidity()\":[{\"notice\":\"Thrown when the account doesn't have enough liquidity to redeem or borrow\"}],\"InsufficientShortfall()\":[{\"notice\":\"Thrown when trying to liquidate a healthy account\"}],\"InvalidCollateralFactor()\":[{\"notice\":\"Thrown when collateral factor exceeds the upper bound\"}],\"InvalidLiquidationThreshold()\":[{\"notice\":\"Thrown when liquidation threshold exceeds the collateral factor\"}],\"MarketAlreadyListed(address)\":[{\"notice\":\"Thrown when trying to add a market that is already listed\"}],\"MarketNotCollateral(address,address)\":[{\"notice\":\"Thrown when user is not member of market\"}],\"MarketNotListed(address)\":[{\"notice\":\"Thrown when the market is not listed\"}],\"MaxLoopsLimitExceeded(uint256,uint256)\":[{\"notice\":\"Thrown an error on maxLoopsLimit exceeds for any loop\"}],\"MinimalCollateralViolated(uint256,uint256)\":[{\"notice\":\"Thrown during the liquidation if user's total collateral amount is lower than a predefined threshold. In this case only batch liquidations (either liquidateAccount or healAccount) are available.\"}],\"NonzeroBorrowBalance()\":[{\"notice\":\"Thrown if the user is trying to exit a market in which they have an outstanding debt\"}],\"PriceError(address)\":[{\"notice\":\"Thrown when the oracle returns an invalid price for some asset\"}],\"SnapshotError(address,address)\":[{\"notice\":\"Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\"}],\"SupplyCapExceeded(address,uint256)\":[{\"notice\":\"Thrown if the supply cap is exceeded\"}],\"TooMuchRepay()\":[{\"notice\":\"Thrown when trying to repay more than allowed by close factor\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"Thrown when the action is prohibited by AccessControlManager\"}],\"UnexpectedSender(address,address)\":[{\"notice\":\"Thrown when the action is only available to specific sender, but the real sender was different\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"ActionPausedMarket(address,uint8,bool)\":{\"notice\":\"Emitted when an action is paused on a market\"},\"MarketEntered(address,address)\":{\"notice\":\"Emitted when an account enters a market\"},\"MarketExited(address,address)\":{\"notice\":\"Emitted when an account exits a market\"},\"MarketSupported(address)\":{\"notice\":\"Emitted when a market is supported\"},\"MaxLoopsLimitUpdated(uint256,uint256)\":{\"notice\":\"Emitted when max loops limit is set\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when access control manager contract address is changed\"},\"NewBorrowCap(address,uint256)\":{\"notice\":\"Emitted when borrow cap for a vToken is changed\"},\"NewCloseFactor(uint256,uint256)\":{\"notice\":\"Emitted when close factor is changed by admin\"},\"NewCollateralFactor(address,uint256,uint256)\":{\"notice\":\"Emitted when a collateral factor is changed by admin\"},\"NewLiquidationIncentive(uint256,uint256)\":{\"notice\":\"Emitted when liquidation incentive is changed by admin\"},\"NewLiquidationThreshold(address,uint256,uint256)\":{\"notice\":\"Emitted when liquidation threshold is changed by admin\"},\"NewMinLiquidatableCollateral(uint256,uint256)\":{\"notice\":\"Emitted when the collateral threshold (in USD) for non-batch liquidations is changed\"},\"NewPriceOracle(address,address)\":{\"notice\":\"Emitted when price oracle is changed\"},\"NewRewardsDistributor(address,address)\":{\"notice\":\"Emitted when a rewards distributor is added\"},\"NewSupplyCap(address,uint256)\":{\"notice\":\"Emitted when supply cap for a vToken is changed\"}},\"kind\":\"user\",\"methods\":{\"accessControlManager()\":{\"notice\":\"Returns the address of the access control manager contract\"},\"accountAssets(address,uint256)\":{\"notice\":\"Per-account mapping of \\\"assets you are in\\\"\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"addRewardsDistributor(address)\":{\"notice\":\"Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\"},\"allMarkets(uint256)\":{\"notice\":\"A list of all markets\"},\"borrowCaps(address)\":{\"notice\":\"Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\"},\"checkMembership(address,address)\":{\"notice\":\"Returns whether the given account is entered in a given market\"},\"closeFactorMantissa()\":{\"notice\":\"Multiplier used to calculate the maximum repayAmount when liquidating a borrow\"},\"enterMarkets(address[])\":{\"notice\":\"Add assets to be included in account liquidity calculation; enabling them to be used as collateral\"},\"exitMarket(address)\":{\"notice\":\"Removes asset from sender's account liquidity calculation; disabling them as collateral\"},\"getAccountLiquidity(address)\":{\"notice\":\"Determine the current account liquidity with respect to liquidation threshold requirements\"},\"getAllMarkets()\":{\"notice\":\"Return all of the markets\"},\"getAssetsIn(address)\":{\"notice\":\"Returns the assets an account has entered\"},\"getBorrowingPower(address)\":{\"notice\":\"Determine the current account liquidity with respect to collateral requirements\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"notice\":\"Determine what the account liquidity would be if the given amounts were redeemed/borrowed\"},\"getRewardDistributors()\":{\"notice\":\"Return all reward distributors for this pool\"},\"getRewardsByMarket(address)\":{\"notice\":\"Returns reward speed given a vToken\"},\"healAccount(address)\":{\"notice\":\"Seizes all the remaining collateral, makes msg.sender repay the existing borrows, and treats the rest of the debt as bad debt (for each market). The sender has to repay a certain percentage of the debt, computed as collateral / (borrows * liquidationIncentive).\"},\"isComptroller()\":{\"notice\":\"A marker method that returns true for a valid Comptroller contract\"},\"isDeprecated(address)\":{\"notice\":\"Check if a vToken market has been deprecated\"},\"isMarketListed(address)\":{\"notice\":\"Check if a market is marked as listed (active)\"},\"liquidateAccount(address,(address,address,uint256)[])\":{\"notice\":\"Liquidates all borrows of the borrower. Callable only if the collateral is less than a predefined threshold, and the account collateral can be seized to cover all borrows. If the collateral is higher than the threshold, use regular liquidations. If the collateral is below the threshold, and the account is insolvent, use healAccount.\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"liquidationIncentiveMantissa()\":{\"notice\":\"Multiplier representing the discount on collateral that a liquidator receives\"},\"markets(address)\":{\"notice\":\"Official mapping of vTokens -> Market metadata\"},\"minLiquidatableCollateral()\":{\"notice\":\"Minimal collateral required for regular (non-batch) liquidations\"},\"oracle()\":{\"notice\":\"Oracle which gives the price of any given asset\"},\"preBorrowHook(address,address,uint256)\":{\"notice\":\"disable-eslint\"},\"preLiquidateHook(address,address,address,uint256,bool)\":{\"notice\":\"Checks if the liquidation should be allowed to occur\"},\"preMintHook(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to mint tokens in the given market\"},\"preRedeemHook(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to redeem tokens in the given market\"},\"preRepayHook(address,address)\":{\"notice\":\"Checks if the account should be allowed to repay a borrow in the given market\"},\"preSeizeHook(address,address,address,address)\":{\"notice\":\"Checks if the seizing of assets should be allowed to occur\"},\"preTransferHook(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to transfer tokens in the given market\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of AccessControlManager\"},\"setActionsPaused(address[],uint8[],bool)\":{\"notice\":\"Pause/unpause specified actions\"},\"setCloseFactor(uint256)\":{\"notice\":\"Sets the closeFactor to use when liquidating borrows\"},\"setCollateralFactor(address,uint256,uint256)\":{\"notice\":\"Sets the collateralFactor for a market\"},\"setLiquidationIncentive(uint256)\":{\"notice\":\"Sets liquidationIncentive\"},\"setMarketBorrowCaps(address[],uint256[])\":{\"notice\":\"Set the given borrow caps for the given vToken markets. 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 markets. Supply that brings total Supply to or above supply cap will revert.\"},\"setMaxLoopsLimit(uint256)\":{\"notice\":\"Set the for loop iteration limit to avoid DOS\"},\"setMinLiquidatableCollateral(uint256)\":{\"notice\":\"Set the given collateral threshold for non-batch liquidations. Regular liquidations will fail if the collateral amount is less than this threshold. Liquidators should use batch operations like liquidateAccount or healAccount.\"},\"setPriceOracle(address)\":{\"notice\":\"Sets a new price oracle for the Comptroller\"},\"supplyCaps(address)\":{\"notice\":\"Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\"},\"supportMarket(address)\":{\"notice\":\"Add the market to the markets mapping and set it as listed\"},\"updatePrices(address)\":{\"notice\":\"Update the prices of all the tokens associated with the provided account\"}},\"notice\":\"The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating, and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow, as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed the `minLiquidatableCollateral` for the `Comptroller`: - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool. - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic verifying that the repay amount does not exceed the close factor.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller.sol\":\"Comptroller\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x40031b19684ca0c912e794d08c2c0b0d8be77d3c1bdc937830a0658eff899650\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 badDebt = VToken(vToken).badDebt();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x73fdb4e4b2a2cfec75b0ef5a19491c4136a7953e1239989fb77ed26c1b7a77ac\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n // The block number at which to stop rewards\\n uint32 lastRewardingBlock;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n /// @notice Emitted when a reward token last rewarding block for supply is updated\\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n */\\n function setLastRewardingBlocks(\\n VToken[] calldata vTokens,\\n uint32[] calldata supplyLastRewardingBlocks,\\n uint32[] calldata borrowLastRewardingBlocks\\n ) external {\\n _checkAccessAllowed(\\\"setLastRewardingBlock(address[],uint32[],uint32[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ) {\\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for a single market.\\n * @param vToken market's whose reward token last rewarding block to be updated\\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n */\\n function _setLastRewardingBlock(\\n VToken vToken,\\n uint32 supplyLastRewardingBlock,\\n uint32 borrowLastRewardingBlock\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n uint256 blockNumber = getBlockNumber();\\n\\n require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n require(\\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n require(\\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n\\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n }\\n\\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\\n blockNumber = supplyState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\\n blockNumber = borrowState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0x0e5bede4edc4346e689de0adcf98dc9642feb55d44c1916715741c5937a34d52\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200551e3803806200551e833981016040819052620000349162000149565b6200003f816200005d565b6001600160a01b0381166080526200005662000088565b506200017b565b6001600160a01b03811662000085576040516342bcdf7f60e11b815260040160405180910390fd5b50565b600054610100900460ff1615620000f55760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161462000147576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200015c57600080fd5b81516001600160a01b03811681146200017457600080fd5b9392505050565b6080516153806200019e600039600081816106b20152612b4601526153806000f3fe608060405234801561001057600080fd5b506004361061035c5760003560e01c80638e6470ea116101d3578063c488847b11610104578063e30c3978116100a2578063e89d51ad1161007c578063e89d51ad14610807578063eade3eed1461081a578063ede4edd01461082d578063f2fde38b1461084057600080fd5b8063e30c3978146107da578063e85a2960146107eb578063e8755446146107fe57600080fd5b8063da35a26f116100de578063da35a26f14610798578063db5c65de146107ab578063dce15449146107b4578063df71403b146107c757600080fd5b8063c488847b1461074a578063cab4f84c14610772578063d136af441461078557600080fd5b8063afcff50f11610171578063b4a0bdf31161014b578063b4a0bdf3146106fc578063be26317e1461070d578063c0891ba914610717578063c29982381461072a57600080fd5b8063afcff50f146106ad578063b0772d0b146106d4578063b2068e84146106dc57600080fd5b8063929fe9a1116101ad578063929fe9a11461063357806394543c1514610674578063a843108114610687578063abfceffc1461069a57600080fd5b80638e6470ea146105bd5780638e8f294b146105d0578063921363951461062057600080fd5b8063528a174c116102ad57806361252fd11161024b57806379ba50971161022557806379ba50971461057e5780637dc0d1d01461058657806380d45a2d146105995780638da5cb5b146105ac57600080fd5b806361252fd11461054e5780636d0be88d14610563578063715018a61461057657600080fd5b806356aaee2d1161028757806356aaee2d146105025780635c21b6c5146105155780635cc4fdeb146105285780635ec88c791461053b57600080fd5b8063528a174c146104b157806352d84d1e146104c4578063530e784f146104ef57600080fd5b806324aaa2201161031a5780634a584432116102f45780634a584432146104475780634ada90af146104675780634e79238f14610470578063520b6c741461049e57600080fd5b806324aaa220146103f55780632bce219c146104085780633d98a1e51461041b57600080fd5b80627e3dd21461036157806302c3bcbb146103795780630e32cb86146103a757806312348e96146103bc578063186db48f146103cf5780631bc41f28146103e2575b600080fd5b60015b60405190151581526020015b60405180910390f35b61039961038736600461491b565b60d16020526000908152604090205481565b604051908152602001610370565b6103ba6103b536600461491b565b610853565b005b6103ba6103ca366004614938565b610867565b6103ba6103dd36600461499d565b6109cd565b6103ba6103f0366004614a09565b610b46565b6103ba610403366004614a73565b610f15565b6103ba610416366004614af7565b610fe2565b61036461042936600461491b565b6001600160a01b0316600090815260cd602052604090205460ff1690565b61039961045536600461491b565b60cf6020526000908152604090205481565b61039960cb5481565b61048361047e366004614b7f565b6113c9565b60408051938452602084019290925290820152606001610370565b6103ba6104ac366004614938565b6113fa565b6104836104bf36600461491b565b611458565b6104d76104d2366004614938565b611483565b6040516001600160a01b039091168152602001610370565b6103ba6104fd36600461491b565b6114ad565b6103ba61051036600461491b565b611511565b6103ba61052336600461491b565b611734565b6103ba610536366004614bc5565b611860565b61048361054936600461491b565b611a9d565b610556611aaf565b6040516103709190614bfa565b6103ba610571366004614c47565b611b11565b6103ba611c87565b6103ba611c9b565b60c9546104d7906001600160a01b031681565b6103ba6105a7366004614938565b611d12565b6033546001600160a01b03166104d7565b6103ba6105cb366004614c98565b611d23565b6106036105de36600461491b565b60cd6020526000908152604090208054600182015460029092015460ff909116919083565b604080519315158452602084019290925290820152606001610370565b6103ba61062e36600461491b565b611e39565b610364610641366004614cd9565b6001600160a01b03808216600090815260cd60209081526040808320938616835260039093019052205460ff1692915050565b61036461068236600461491b565b61221f565b6103ba610695366004614938565b6122c8565b6105566106a836600461491b565b6123b6565b6104d77f000000000000000000000000000000000000000000000000000000000000000081565b61055661242c565b6106ef6106ea36600461491b565b61248c565b6040516103709190614d12565b6097546001600160a01b03166104d7565b6103996101075481565b6103ba610725366004614c98565b6126cf565b61073d610738366004614d8a565b61295f565b6040516103709190614e4f565b61075d610758366004614c98565b612a16565b60408051928352602083019190915201610370565b6103ba61078036600461491b565b612b41565b6103ba61079336600461499d565b612d75565b6103ba6107a6366004614e87565b612f32565b61039960d05481565b6104d76107c2366004614eac565b613053565b6103ba6107d5366004614c98565b61308b565b6065546001600160a01b03166104d7565b6103646107f9366004614ee7565b6134ba565b61039960ca5481565b6103ba610815366004614f1c565b613511565b6103ba610828366004614cd9565b613701565b61039961083b36600461491b565b61393b565b6103ba61084e36600461491b565b613bad565b61085b613c1e565b61086481613c78565b50565b6108a56040518060400160405280601781526020017f736574436c6f7365466163746f722875696e7432353629000000000000000000815250613d2f565b80670c7d713b49da000010156109195760405162461bcd60e51b815260206004820152602e60248201527f436c6f736520666163746f722067726561746572207468616e206d6178696d7560448201526d369031b637b9b2903330b1ba37b960911b60648201526084015b60405180910390fd5b8066b1a2bc2ec5000011156109875760405162461bcd60e51b815260206004820152602e60248201527f436c6f736520666163746f7220736d616c6c6572207468616e206d696e696d7560448201526d369031b637b9b2903330b1ba37b960911b6064820152608401610910565b60ca80549082905560408051828152602081018490527f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd991015b60405180910390a15050565b6109ee60405180606001604052806028815260200161528060289139613d2f565b828181158015906109fe57508082145b610a3a5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b6044820152606401610910565b610a4382613dcd565b60005b82811015610b3d57848482818110610a6057610a60614f76565b9050602002013560cf6000898985818110610a7d57610a7d614f76565b9050602002016020810190610a92919061491b565b6001600160a01b03168152602081019190915260400160002055868682818110610abe57610abe614f76565b9050602002016020810190610ad3919061491b565b6001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110610b0f57610b0f614f76565b90506020020135604051610b2591815260200190565b60405180910390a2610b3681614fa2565b9050610a46565b50505050505050565b610b51846004613e00565b6001600160a01b038416600090815260cd60205260409020805460ff16610b9657604051635a9a1eb960e11b81526001600160a01b0386166004820152602401610910565b306001600160a01b03851603610c3e57306001600160a01b0316856001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c129190614fbb565b6001600160a01b031614610c3957604051630c73eb0560e01b815260040160405180910390fd5b610d76565b6001600160a01b038416600090815260cd602052604090205460ff16610c8257604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b836001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce49190614fbb565b6001600160a01b0316856001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f9190614fbb565b6001600160a01b031614610d7657604051630c73eb0560e01b815260040160405180910390fd5b6001600160a01b038216600090815260038201602052604090205460ff16610db5578482604051630cdfb2db60e31b8152600401610910929190614fd8565b60d35460005b81811015610b3d57600060d38281548110610dd857610dd8614f76565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b038a8116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015610e2b57600080fd5b505af1158015610e3f573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150610e71908b908990600401614fd8565b600060405180830381600087803b158015610e8b57600080fd5b505af1158015610e9f573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150610ed1908b908a90600401614fd8565b600060405180830381600087803b158015610eeb57600080fd5b505af1158015610eff573d6000803e3d6000fd5b505050505080610f0e90614fa2565b9050610dbb565b610f366040518060600160405280602a81526020016152f9602a9139613d2f565b8382610f4a610f458284614ff2565b613dcd565b60005b82811015610fd85760005b82811015610fc757610fb7898984818110610f7557610f75614f76565b9050602002016020810190610f8a919061491b565b888884818110610f9c57610f9c614f76565b9050602002016020810190610fb19190615011565b87613e2c565b610fc081614fa2565b9050610f58565b50610fd181614fa2565b9050610f4d565b5050505050505050565b6000610ff084613f3a613f6e565b905060d054816000015111156110275760d0548151604051631a451c0f60e21b815260048101929092526024820152604401610910565b6000611047604051806020016040528060cb548152508360400151613fbd565b82519091508110611078578151604051632c1f8ef160e21b8152610910918391600401918252602082015260400190565b8160a0015160000361109d5760405163095bf33360e01b815260040160405180910390fd5b826110ac610f4560028361502c565b60005b818110156112a45760cd60008787848181106110cd576110cd614f76565b90506060020160200160208101906110e5919061491b565b6001600160a01b0316815260208101919091526040016000205460ff166111555785858281811061111857611118614f76565b9050606002016020016020810190611130919061491b565b604051635a9a1eb960e11b81526001600160a01b039091166004820152602401610910565b60cd600087878481811061116b5761116b614f76565b611181926020606090920201908101915061491b565b6001600160a01b0316815260208101919091526040016000205460ff166111ca578585828181106111b4576111b4614f76565b611130926020606090920201908101915061491b565b368686838181106111dd576111dd614f76565b90506060020190508060200160208101906111f8919061491b565b6001600160a01b0316638bbdb6db338a604085013561121a602087018761491b565b60405160e086901b6001600160e01b03191681526001600160a01b0394851660048201529284166024840152604483019190915290911660648201526001608482015260a401600060405180830381600087803b15801561127a57600080fd5b505af115801561128e573d6000803e3d6000fd5b50505050508061129d90614fa2565b90506110af565b506001600160a01b038616600090815260cc602090815260408083208054825181850281018501909352808352919290919083018282801561130f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112f1575b505083519394506000925050505b818110156113be57600061134a84838151811061133c5761133c614f76565b60200260200101518b613fdd565b5091505080156113ad5760405162461bcd60e51b815260206004820152602860248201527f4e6f6e7a65726f20626f72726f772062616c616e6365206166746572206c69716044820152673ab4b230ba34b7b760c11b6064820152608401610910565b506113b781614fa2565b905061131d565b505050505050505050565b6000806000806113de888888886140846140b8565b608081015160a09091015160009a919950975095505050505050565b61141b6040518060600160405280602581526020016152a860259139613d2f565b60d080549082905560408051828152602081018490527eb4f4f153ad7f1397564a8830fef092481e8cf6a2cd3ff04f96d10ba51200a591016109c1565b60008060008061146a85614084613f6e565b608081015160a090910151600097919650945092505050565b60ce818154811061149357600080fd5b6000918252602090912001546001600160a01b0316905081565b6114b5613c1e565b6114be816142ed565b60c980546001600160a01b038381166001600160a01b03198316179092556040519116907fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22906109c19083908590614fd8565b611519613c1e565b6001600160a01b038116600090815260d4602052604090205460ff16156115735760405162461bcd60e51b815260206004820152600e60248201526d616c72656164792065786973747360901b6044820152606401610910565b60d354611584610f4582600161504e565b60d3805460018082019092557f915c3eb987b20e1af620c1403197bf687fb7f18513b3a73fde6e78c7072c41a60180546001600160a01b0319166001600160a01b038516908117909155600090815260d460205260408120805460ff191690921790915560ce54905b8181101561168d57836001600160a01b0316632a869a4d60ce838154811061161757611617614f76565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401600060405180830381600087803b15801561166457600080fd5b505af1158015611678573d6000803e3d6000fd5b505050508061168690614fa2565b90506115ed565b50826001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f09190614fbb565b6001600160a01b0316836001600160a01b03167f066a44d77db1581603d7d8ca1ca494756c0d359c7ffacd9b2c8f78dab7aceae260405160405180910390a3505050565b6001600160a01b038116600090815260cc602090815260408083208054825181850281018501909352808352919290919083018282801561179e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611780575b5050835160c954949550936001600160a01b0316925060009150505b8281101561185957816001600160a01b03166396e85ced8583815181106117e3576117e3614f76565b60200260200101516040518263ffffffff1660e01b815260040161181691906001600160a01b0391909116815260200190565b600060405180830381600087803b15801561183057600080fd5b505af1158015611844573d6000803e3d6000fd5b505050508061185290614fa2565b90506117ba565b5050505050565b6118816040518060600160405280602c81526020016152cd602c9139613d2f565b6001600160a01b038316600090815260cd60205260409020805460ff166118c657604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b670c7d713b49da00008311156118ef576040516302f22cad60e61b815260040160405180910390fd5b670de0b6b3a76400008211156119175760405162f9474b60e61b815260040160405180910390fd5b828210156119375760405162f9474b60e61b815260040160405180910390fd5b82158015906119b1575060c95460405163fc57d4df60e01b81526001600160a01b0386811660048301529091169063fc57d4df90602401602060405180830381865afa15801561198b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119af9190615066565b155b156119d95760405162e52a7d60e41b81526001600160a01b0385166004820152602401610910565b6001810154838114611a375760018201849055604080516001600160a01b0387168152602081018390529081018590527f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59060600160405180910390a15b6002820154838114611a955760028301849055604080516001600160a01b0388168152602081018390529081018590527f9e92c7d5fef69846094f3ddcadcb9402c6ba469c461368714f1cabd8ef48b5919060600160405180910390a15b505050505050565b60008060008061146a85613f3a613f6e565b606060d3805480602002602001604051908101604052809291908181526020018280548015611b0757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611ae9575b5050505050905090565b611b1c846006613e00565b611b27848483614314565b60d35460005b81811015611a9557600060d38281548110611b4a57611b4a614f76565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03898116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015611b9d57600080fd5b505af1158015611bb1573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611be3908a908a90600401614fd8565b600060405180830381600087803b158015611bfd57600080fd5b505af1158015611c11573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611c43908a908990600401614fd8565b600060405180830381600087803b158015611c5d57600080fd5b505af1158015611c71573d6000803e3d6000fd5b505050505080611c8090614fa2565b9050611b2d565b611c8f613c1e565b611c9960006143c2565b565b60655433906001600160a01b03168114611d095760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610910565b610864816143c2565b611d1a613c1e565b610864816143db565b611d2e836001613e00565b611d39838383614314565b60d35460005b8181101561185957600060d38281548110611d5c57611d5c614f76565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03888116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015611daf57600080fd5b505af1158015611dc3573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611df59089908990600401614fd8565b600060405180830381600087803b158015611e0f57600080fd5b505af1158015611e23573d6000803e3d6000fd5b505050505080611e3290614fa2565b9050611d3f565b6001600160a01b038116600090815260cc6020908152604080832080548251818502810185019093528083529192909190830182828015611ea357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611e85575b5050835160c954949550933393506001600160a01b03169150600090505b83811015611fde57848181518110611edb57611edb614f76565b60200260200101516001600160a01b031663a6afed956040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f469190615066565b50816001600160a01b03166396e85ced868381518110611f6857611f68614f76565b60200260200101516040518263ffffffff1660e01b8152600401611f9b91906001600160a01b0391909116815260200190565b600060405180830381600087803b158015611fb557600080fd5b505af1158015611fc9573d6000803e3d6000fd5b5050505080611fd790614fa2565b9050611ec1565b50506000611fee85613f3a613f6e565b905060d054816000015111156120255760d0548151604051631a451c0f60e21b815260048101929092526024820152604401610910565b8060a0015160000361204a5760405163095bf33360e01b815260040160405180910390fd5b60408051602080820183528351825282518082018452848401518152835191820190935260cb54815290916000916120829190614477565b9050600061209083836144bf565b90506120b46040518060200160405280670de0b6b3a7640000815250825190511090565b156120df5781518351604051631a451c0f60e21b815260048101929092526024820152604401610910565b60005b868110156113be5760008882815181106120fe576120fe614f76565b60200260200101519050600080612115838d613fdd565b509150915060006121268683613fbd565b905082156121995760405163b2a02ff160e01b81526001600160a01b038b811660048301528e811660248301526044820185905285169063b2a02ff190606401600060405180830381600087803b15801561218057600080fd5b505af1158015612194573d6000803e3d6000fd5b505050505b811561220a5760405163227f37ff60e11b81526001600160a01b038b811660048301528e81166024830152604482018390528516906344fe6ffe90606401600060405180830381600087803b1580156121f157600080fd5b505af1158015612205573d6000803e3d6000fd5b505050505b505050508061221890614fa2565b90506120e2565b6001600160a01b038116600090815260cd602052604081206001015415801561224e575061224e8260026134ba565b80156122c25750670de0b6b3a7640000826001600160a01b031663173b99046040518163ffffffff1660e01b8152600401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c09190615066565b145b92915050565b670de0b6b3a764000081101561233a5760405162461bcd60e51b815260206004820152603160248201527f6c69717569646174696f6e20696e63656e746976652073686f756c64206265206044820152700cee4cac2e8cae440e8d0c2dc4062ca627607b1b6064820152608401610910565b6123786040518060400160405280602081526020017f7365744c69717569646174696f6e496e63656e746976652875696e7432353629815250613d2f565b60cb80549082905560408051828152602081018490527faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec131691016109c1565b6001600160a01b038116600090815260cc6020908152604080832080548251818502810185019093528083526060949383018282801561241f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612401575b5093979650505050505050565b606060ce805480602002602001604051908101604052809291908181526020018280548015611b07576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311611ae9575050505050905090565b60d3546060908067ffffffffffffffff8111156124ab576124ab614d74565b60405190808252806020026020018201604052801561250957816020015b6124f6604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b8152602001906001900390816124c95790505b50915060005b818110156126c857600060d3828154811061252c5761252c614f76565b60009182526020808320909101546040805163f7c618c160e01b815290516001600160a01b039092169450849263f7c618c1926004808401938290030181865afa15801561257e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a29190614fbb565b604080516060810182526001600160a01b0380841682529151631d31307360e21b815289831660048201529293509160208301918516906374c4c1cc90602401602060405180830381865afa1580156125ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126239190615066565b8152604051637c05a7c560e01b81526001600160a01b038981166004830152602090920191851690637c05a7c590602401602060405180830381865afa158015612671573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126959190615066565b8152508584815181106126aa576126aa614f76565b60200260200101819052505050806126c190614fa2565b905061250f565b5050919050565b6126da836000613e00565b6001600160a01b038316600090815260cd602052604090205460ff1661271e57604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b038316600090815260d16020526040902054600019811461285f576000846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612780573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a49190615066565b905060006040518060200160405280876001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128159190615066565b9052905060006128268284876144f9565b90508381111561285b5760405163db33be3d60e01b81526001600160a01b038816600482015260248101859052604401610910565b5050505b60d35460005b81811015611a9557600060d3828154811061288257612882614f76565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03898116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b1580156128d557600080fd5b505af11580156128e9573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd915061291b908a908a90600401614fd8565b600060405180830381600087803b15801561293557600080fd5b505af1158015612949573d6000803e3d6000fd5b50505050508061295890614fa2565b9050612865565b805160609060008167ffffffffffffffff81111561297f5761297f614d74565b6040519080825280602002602001820160405280156129a8578160200160208202803683370190505b50905060005b82811015612a0e5760008582815181106129ca576129ca614f76565b602002602001015190506129de8133614523565b60008383815181106129f2576129f2614f76565b602090810291909101015250612a0781614fa2565b90506129ae565b509392505050565b6000806000612a248661461f565b90506000612a318661461f565b90506000866001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a979190615066565b90506000612ab16040518060200160405280600081525090565b60408051602080820183526000808352835180830185529081528351808301855260cb54815284519283019094528882529192612aed91614477565b9250612b15604051806020016040528088815250604051806020016040528088815250614477565b9150612b2183836144bf565b9050612b2d818b613fbd565b60009d909c509a5050505050505050505050565b612b6a7f00000000000000000000000000000000000000000000000000000000000000006146be565b6001600160a01b038116600090815260cd602052604090205460ff1615612baf5760405163d005ce4760e01b81526001600160a01b0382166004820152602401610910565b806001600160a01b0316633d9ea3a16040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c11919061507f565b612c5d5760405162461bcd60e51b815260206004820152601b60248201527f436f6d7074726f6c6c65723a20496e76616c69642076546f6b656e00000000006044820152606401610910565b6001600160a01b038116600090815260cd60205260408120805460ff19166001908117825581018290556002810191909155612c98826146eb565b60d35460005b81811015612d325760d38181548110612cb957612cb9614f76565b600091825260209091200154604051632a869a4d60e01b81526001600160a01b03868116600483015290911690632a869a4d90602401600060405180830381600087803b158015612d0957600080fd5b505af1158015612d1d573d6000803e3d6000fd5b5050505080612d2b90614fa2565b9050612c9e565b506040516001600160a01b03841681527faf16ad15f9e29d5140e8e81a30a92a755aa8edff3d301053c84392b70c0d09a3906020015b60405180910390a1505050565b612d9660405180606001604052806028815260200161532360289139613d2f565b826000819003612de45760405162461bcd60e51b8152602060048201526019602482015278696e76616c6964206e756d626572206f66206d61726b65747360381b6044820152606401610910565b808214612e2f5760405162461bcd60e51b8152602060048201526019602482015278696e76616c6964206e756d626572206f66206d61726b65747360381b6044820152606401610910565b612e3881613dcd565b60005b81811015611a9557838382818110612e5557612e55614f76565b9050602002013560d16000888885818110612e7257612e72614f76565b9050602002016020810190612e87919061491b565b6001600160a01b03168152602081019190915260400160002055858582818110612eb357612eb3614f76565b9050602002016020810190612ec8919061491b565b6001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f8858584818110612f0457612f04614f76565b90506020020135604051612f1a91815260200190565b60405180910390a2612f2b81614fa2565b9050612e3b565b600054610100900460ff1615808015612f525750600054600160ff909116105b80612f6c5750303b158015612f6c575060005460ff166001145b612fcf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610910565b6000805460ff191660011790558015612ff2576000805461ff0019166101001790555b612ffa6147ba565b613003826147e9565b61300c836143db565b801561304e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001612d68565b505050565b60cc602052816000526040600020818154811061306f57600080fd5b6000918252602090912001546001600160a01b03169150829050565b613096836002613e00565b6001600160a01b038316600090815260cd602052604090205460ff166130da57604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b03808416600090815260cd60209081526040808320938616835260039093019052205460ff1661311e57613114836146be565b61311e3383614523565b61312782611734565b60c95460405163fc57d4df60e01b81526001600160a01b0385811660048301529091169063fc57d4df90602401602060405180830381865afa158015613171573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131959190615066565b6000036131bf5760405162e52a7d60e41b81526001600160a01b0384166004820152602401610910565b6001600160a01b038316600090815260cf602052604090205460001981146132fd576000846001600160a01b03166347bd37186040518163ffffffff1660e01b8152600401602060405180830381865afa158015613221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132459190615066565b90506000856001600160a01b031663bbcac5576040518163ffffffff1660e01b8152600401602060405180830381865afa158015613287573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ab9190615066565b90506000816132ba868561504e565b6132c4919061504e565b9050838111156132f957604051632e649eed60e01b81526001600160a01b038816600482015260248101859052604401610910565b5050505b600061330f84866000866140846140b8565b60a0810151909150156133355760405163bb55fd2760e01b815260040160405180910390fd5b60006040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613380573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a49190615066565b905260d35490915060005b81811015610fd857600060d382815481106133cc576133cc614f76565b600091825260209091200154604051632352607960e01b81526001600160a01b038b811660048301528651602483015290911691508190632352607990604401600060405180830381600087803b15801561342657600080fd5b505af115801561343a573d6000803e3d6000fd5b5050604051636a95ddef60e01b81526001600160a01b038c811660048301528b811660248301528751604483015284169250636a95ddef9150606401600060405180830381600087803b15801561349057600080fd5b505af11580156134a4573d6000803e3d6000fd5b5050505050806134b390614fa2565b90506133af565b6001600160a01b038216600090815260d260205260408120818360088111156134e5576134e561509c565b60088111156134f6576134f661509c565b815260208101919091526040016000205460ff169392505050565b61351c856005613e00565b61352583611734565b6001600160a01b038516600090815260cd602052604090205460ff1661356957604051635a9a1eb960e11b81526001600160a01b0386166004820152602401610910565b6001600160a01b038416600090815260cd602052604090205460ff166135ad57604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b6040516395dd919360e01b81526001600160a01b038481166004830152600091908716906395dd919390602401602060405180830381865afa1580156135f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061361b9190615066565b9050818061362d575061362d8661221f565b1561365957808311156136535760405163e46c155960e01b815260040160405180910390fd5b50611859565b600061366785613f3a613f6e565b905060d05481600001511161369d5760d0548151604051636e61bb0560e11b815260048101929092526024820152604401610910565b8060a001516000036136c25760405163095bf33360e01b815260040160405180910390fd5b60006136de604051806020016040528060ca5481525084613fbd565b905080851115610fd85760405163e46c155960e01b815260040160405180910390fd5b61370c826003613e00565b60c9546040516396e85ced60e01b81526001600160a01b038481166004830152909116906396e85ced90602401600060405180830381600087803b15801561375357600080fd5b505af1158015613767573d6000803e3d6000fd5b505050506001600160a01b038216600090815260cd602052604090205460ff166137af57604051635a9a1eb960e11b81526001600160a01b0383166004820152602401610910565b60d35460005b818110156139355760006040518060200160405280866001600160a01b031663aa5af0fd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382c9190615066565b8152509050600060d3838154811061384657613846614f76565b600091825260209091200154604051632352607960e01b81526001600160a01b0388811660048301528451602483015290911691508190632352607990604401600060405180830381600087803b1580156138a057600080fd5b505af11580156138b4573d6000803e3d6000fd5b5050604051636a95ddef60e01b81526001600160a01b03898116600483015288811660248301528551604483015284169250636a95ddef9150606401600060405180830381600087803b15801561390a57600080fd5b505af115801561391e573d6000803e3d6000fd5b5050505050508061392e90614fa2565b90506137b5565b50505050565b6000613948826008613e00565b816000806139568333613fdd565b50915091508060001461397c5760405163f8a5d66d60e01b815260040160405180910390fd5b613987853384614314565b6001600160a01b038316600090815260cd60209081526040808320338452600381019092529091205460ff166139c35750600095945050505050565b3360009081526003820160209081526040808320805460ff1916905560cc825280832080548251818502810185019093528083529192909190830182828015613a3557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613a17575b5050835193945083925060009150505b82811015613a9757876001600160a01b0316848281518110613a6957613a69614f76565b60200260200101516001600160a01b031603613a8757809150613a97565b613a9081614fa2565b9050613a45565b50818110613aa757613aa76150b2565b33600090815260cc6020526040902080548190613ac6906001906150c8565b81548110613ad657613ad6614f76565b9060005260206000200160009054906101000a90046001600160a01b0316818381548110613b0657613b06614f76565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080805480613b4457613b446150df565b600082815260208120820160001990810180546001600160a01b031916905590910190915560405133916001600160a01b038b16917fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d9190a35060009998505050505050505050565b613bb5613c1e565b606580546001600160a01b0383166001600160a01b03199091168117909155613be66033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b03163314611c995760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610910565b6001600160a01b038116613cdc5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b6064820152608401610910565b609780546001600160a01b038381166001600160a01b03198316179092556040519116907f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0906109c19083908590614fd8565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab90613d629033908690600401615142565b602060405180830381865afa158015613d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613da3919061507f565b905080613dc957333083604051634a3fa29360e01b815260040161091093929190615166565b5050565b61010754811115610864576101075460405163792bfb1b60e11b8152600481019190915260248101829052604401610910565b613e0a82826134ba565b15613dc95781816040516313b3ccb160e31b81526004016109109291906151b4565b6001600160a01b038316600090815260cd602052604090205460ff16613ea55760405162461bcd60e51b815260206004820152602860248201527f63616e6e6f742070617573652061206d61726b65742074686174206973206e6f6044820152671d081b1a5cdd195960c21b6064820152608401610910565b6001600160a01b038316600090815260d2602052604081208291846008811115613ed157613ed161509c565b6008811115613ee257613ee261509c565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d838383604051612d68939291906151d1565b6040805160208082018352600091829052825180820184526001600160a01b0394909416825260cd90522060020154815290565b613fa76040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b613fb6836000806000866140b8565b9392505050565b600080613fca8484614810565b9050613fd581614838565b949350505050565b6040516361bfb47160e11b81526001600160a01b03828116600483015260009182918291829187169063c37f68e290602401608060405180830381865afa15801561402c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061405091906151fe565b919650945092509050801561407c57858560405163015e34d960e61b8152600401610910929190614fd8565b509250925092565b6040805160208082018352600091829052825180820184526001600160a01b0394909416825260cd90522060010154815290565b6140f16040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6001600160a01b038616600090815260cc602090815260408083208054825181850281018501909352808352919290919083018282801561415b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161413d575b505083519394506000925050505b8181101561428f57600083828151811061418557614185614f76565b60200260200101519050600080600061419e848e613fdd565b925092509250600060405180602001604052806141ba8761461f565b815250905060006141d960405180602001604052808581525083614477565b905060006141f36141ed888e63ffffffff16565b83614477565b905061420481878d602001516144f9565b60208c01528a5161421890839088906144f9565b8b5260408b015161422c90849087906144f9565b8b60400181815250508e6001600160a01b0316876001600160a01b0316036142775761425d818f8d606001516144f9565b60608c018190526142719084908f906144f9565b60608c01525b505050505050508061428890614fa2565b9050614169565b506000836060015184604001516142a6919061504e565b905080846020015111156142cd5760208401518190036080850152600060a08501526142e1565b600060808501526020840151810360a08501525b50505095945050505050565b6001600160a01b038116610864576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b038316600090815260cd60205260409020805460ff1661435957604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b6001600160a01b038316600090815260038201602052604090205460ff166143815750505050565b61438a83611734565b600061439c84868560006140846140b8565b60a0810151909150156118595760405163bb55fd2760e01b815260040160405180910390fd5b606580546001600160a01b031916905561086481614850565b6101075481116144385760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b6064820152608401610910565b61010780549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa91016109c1565b6040805160208101909152600081526040518060200160405280670de0b6b3a76400006144ac866000015186600001516148a2565b6144b6919061502c565b90529392505050565b60408051602081019091526000815260405180602001604052806144b66144f28660000151670de0b6b3a76400006148a2565b85516148ae565b6000806145068585614810565b905061451a61451482614838565b846148ba565b95945050505050565b61452e826007613e00565b6001600160a01b038216600090815260cd60205260409020805460ff1661457357604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b038216600090815260038201602052604090205460ff161561459b57505050565b6001600160a01b0380831660008181526003840160209081526040808320805460ff1916600190811790915560cc835281842080549182018155845291832090910180549488166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a3505050565b60c95460405163fc57d4df60e01b81526001600160a01b038381166004830152600092839291169063fc57d4df90602401602060405180830381865afa15801561466d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146919190615066565b9050806000036122c25760405162e52a7d60e41b81526001600160a01b0384166004820152602401610910565b336001600160a01b03821614610864578033604051634e9383fb60e11b8152600401610910929190614fd8565b60ce5460005b8181101561476457826001600160a01b031660ce828154811061471657614716614f76565b6000918252602090912001546001600160a01b0316036147545760405163d005ce4760e01b81526001600160a01b0384166004820152602401610910565b61475d81614fa2565b90506146f1565b505060ce805460018101825560008290527fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a0180546001600160a01b0319166001600160a01b03841617905554613dc981613dcd565b600054610100900460ff166147e15760405162461bcd60e51b815260040161091090615234565b611c996148c6565b600054610100900460ff1661085b5760405162461bcd60e51b815260040161091090615234565b60408051602081019091526000815260405180602001604052806144b68560000151856148a2565b80516000906122c290670de0b6b3a76400009061502c565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000613fb68284614ff2565b6000613fb6828461502c565b6000613fb6828461504e565b600054610100900460ff166148ed5760405162461bcd60e51b815260040161091090615234565b611c99336143c2565b6001600160a01b038116811461086457600080fd5b8035614916816148f6565b919050565b60006020828403121561492d57600080fd5b8135613fb6816148f6565b60006020828403121561494a57600080fd5b5035919050565b60008083601f84011261496357600080fd5b50813567ffffffffffffffff81111561497b57600080fd5b6020830191508360208260051b850101111561499657600080fd5b9250929050565b600080600080604085870312156149b357600080fd5b843567ffffffffffffffff808211156149cb57600080fd5b6149d788838901614951565b909650945060208701359150808211156149f057600080fd5b506149fd87828801614951565b95989497509550505050565b60008060008060808587031215614a1f57600080fd5b8435614a2a816148f6565b93506020850135614a3a816148f6565b92506040850135614a4a816148f6565b91506060850135614a5a816148f6565b939692955090935050565b801515811461086457600080fd5b600080600080600060608688031215614a8b57600080fd5b853567ffffffffffffffff80821115614aa357600080fd5b614aaf89838a01614951565b90975095506020880135915080821115614ac857600080fd5b50614ad588828901614951565b9094509250506040860135614ae981614a65565b809150509295509295909350565b600080600060408486031215614b0c57600080fd5b8335614b17816148f6565b9250602084013567ffffffffffffffff80821115614b3457600080fd5b818601915086601f830112614b4857600080fd5b813581811115614b5757600080fd5b876020606083028501011115614b6c57600080fd5b6020830194508093505050509250925092565b60008060008060808587031215614b9557600080fd5b8435614ba0816148f6565b93506020850135614bb0816148f6565b93969395505050506040820135916060013590565b600080600060608486031215614bda57600080fd5b8335614be5816148f6565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015614c3b5783516001600160a01b031683529284019291840191600101614c16565b50909695505050505050565b60008060008060808587031215614c5d57600080fd5b8435614c68816148f6565b93506020850135614c78816148f6565b92506040850135614c88816148f6565b9396929550929360600135925050565b600080600060608486031215614cad57600080fd5b8335614cb8816148f6565b92506020840135614cc8816148f6565b929592945050506040919091013590565b60008060408385031215614cec57600080fd5b8235614cf7816148f6565b91506020830135614d07816148f6565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015614d6757815180516001600160a01b0316855286810151878601528501518585015260609093019290850190600101614d2f565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215614d9d57600080fd5b823567ffffffffffffffff80821115614db557600080fd5b818501915085601f830112614dc957600080fd5b813581811115614ddb57614ddb614d74565b8060051b604051601f19603f83011681018181108582111715614e0057614e00614d74565b604052918252848201925083810185019188831115614e1e57600080fd5b938501935b82851015614e4357614e348561490b565b84529385019392850192614e23565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614c3b57835183529284019291840191600101614e6b565b60008060408385031215614e9a57600080fd5b823591506020830135614d07816148f6565b60008060408385031215614ebf57600080fd5b8235614eca816148f6565b946020939093013593505050565b80356009811061491657600080fd5b60008060408385031215614efa57600080fd5b8235614f05816148f6565b9150614f1360208401614ed8565b90509250929050565b600080600080600060a08688031215614f3457600080fd5b8535614f3f816148f6565b94506020860135614f4f816148f6565b93506040860135614f5f816148f6565b9250606086013591506080860135614ae981614a65565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201614fb457614fb4614f8c565b5060010190565b600060208284031215614fcd57600080fd5b8151613fb6816148f6565b6001600160a01b0392831681529116602082015260400190565b600081600019048311821515161561500c5761500c614f8c565b500290565b60006020828403121561502357600080fd5b613fb682614ed8565b60008261504957634e487b7160e01b600052601260045260246000fd5b500490565b6000821982111561506157615061614f8c565b500190565b60006020828403121561507857600080fd5b5051919050565b60006020828403121561509157600080fd5b8151613fb681614a65565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000828210156150da576150da614f8c565b500390565b634e487b7160e01b600052603160045260246000fd5b6000815180845260005b8181101561511b576020818501810151868301820152016150ff565b8181111561512d576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0383168152604060208201819052600090613fd5908301846150f5565b6001600160a01b0384811682528316602082015260606040820181905260009061451a908301846150f5565b600981106151b057634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b038316815260408101613fb66020830184615192565b6001600160a01b0384168152606081016151ee6020830185615192565b8215156040830152949350505050565b6000806000806080858703121561521457600080fd5b505082516020840151604085015160609095015191969095509092509050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d297365744d696e4c6971756964617461626c65436f6c6c61746572616c2875696e7432353629736574436f6c6c61746572616c466163746f7228616464726573732c75696e743235362c75696e7432353629736574416374696f6e7350617573656428616464726573735b5d2c75696e743235365b5d2c626f6f6c297365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d29a2646970667358221220f04d34f9fc5387beb487dbd5d16231b8153559f6560d3a8f7481997be14be4d164736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061035c5760003560e01c80638e6470ea116101d3578063c488847b11610104578063e30c3978116100a2578063e89d51ad1161007c578063e89d51ad14610807578063eade3eed1461081a578063ede4edd01461082d578063f2fde38b1461084057600080fd5b8063e30c3978146107da578063e85a2960146107eb578063e8755446146107fe57600080fd5b8063da35a26f116100de578063da35a26f14610798578063db5c65de146107ab578063dce15449146107b4578063df71403b146107c757600080fd5b8063c488847b1461074a578063cab4f84c14610772578063d136af441461078557600080fd5b8063afcff50f11610171578063b4a0bdf31161014b578063b4a0bdf3146106fc578063be26317e1461070d578063c0891ba914610717578063c29982381461072a57600080fd5b8063afcff50f146106ad578063b0772d0b146106d4578063b2068e84146106dc57600080fd5b8063929fe9a1116101ad578063929fe9a11461063357806394543c1514610674578063a843108114610687578063abfceffc1461069a57600080fd5b80638e6470ea146105bd5780638e8f294b146105d0578063921363951461062057600080fd5b8063528a174c116102ad57806361252fd11161024b57806379ba50971161022557806379ba50971461057e5780637dc0d1d01461058657806380d45a2d146105995780638da5cb5b146105ac57600080fd5b806361252fd11461054e5780636d0be88d14610563578063715018a61461057657600080fd5b806356aaee2d1161028757806356aaee2d146105025780635c21b6c5146105155780635cc4fdeb146105285780635ec88c791461053b57600080fd5b8063528a174c146104b157806352d84d1e146104c4578063530e784f146104ef57600080fd5b806324aaa2201161031a5780634a584432116102f45780634a584432146104475780634ada90af146104675780634e79238f14610470578063520b6c741461049e57600080fd5b806324aaa220146103f55780632bce219c146104085780633d98a1e51461041b57600080fd5b80627e3dd21461036157806302c3bcbb146103795780630e32cb86146103a757806312348e96146103bc578063186db48f146103cf5780631bc41f28146103e2575b600080fd5b60015b60405190151581526020015b60405180910390f35b61039961038736600461491b565b60d16020526000908152604090205481565b604051908152602001610370565b6103ba6103b536600461491b565b610853565b005b6103ba6103ca366004614938565b610867565b6103ba6103dd36600461499d565b6109cd565b6103ba6103f0366004614a09565b610b46565b6103ba610403366004614a73565b610f15565b6103ba610416366004614af7565b610fe2565b61036461042936600461491b565b6001600160a01b0316600090815260cd602052604090205460ff1690565b61039961045536600461491b565b60cf6020526000908152604090205481565b61039960cb5481565b61048361047e366004614b7f565b6113c9565b60408051938452602084019290925290820152606001610370565b6103ba6104ac366004614938565b6113fa565b6104836104bf36600461491b565b611458565b6104d76104d2366004614938565b611483565b6040516001600160a01b039091168152602001610370565b6103ba6104fd36600461491b565b6114ad565b6103ba61051036600461491b565b611511565b6103ba61052336600461491b565b611734565b6103ba610536366004614bc5565b611860565b61048361054936600461491b565b611a9d565b610556611aaf565b6040516103709190614bfa565b6103ba610571366004614c47565b611b11565b6103ba611c87565b6103ba611c9b565b60c9546104d7906001600160a01b031681565b6103ba6105a7366004614938565b611d12565b6033546001600160a01b03166104d7565b6103ba6105cb366004614c98565b611d23565b6106036105de36600461491b565b60cd6020526000908152604090208054600182015460029092015460ff909116919083565b604080519315158452602084019290925290820152606001610370565b6103ba61062e36600461491b565b611e39565b610364610641366004614cd9565b6001600160a01b03808216600090815260cd60209081526040808320938616835260039093019052205460ff1692915050565b61036461068236600461491b565b61221f565b6103ba610695366004614938565b6122c8565b6105566106a836600461491b565b6123b6565b6104d77f000000000000000000000000000000000000000000000000000000000000000081565b61055661242c565b6106ef6106ea36600461491b565b61248c565b6040516103709190614d12565b6097546001600160a01b03166104d7565b6103996101075481565b6103ba610725366004614c98565b6126cf565b61073d610738366004614d8a565b61295f565b6040516103709190614e4f565b61075d610758366004614c98565b612a16565b60408051928352602083019190915201610370565b6103ba61078036600461491b565b612b41565b6103ba61079336600461499d565b612d75565b6103ba6107a6366004614e87565b612f32565b61039960d05481565b6104d76107c2366004614eac565b613053565b6103ba6107d5366004614c98565b61308b565b6065546001600160a01b03166104d7565b6103646107f9366004614ee7565b6134ba565b61039960ca5481565b6103ba610815366004614f1c565b613511565b6103ba610828366004614cd9565b613701565b61039961083b36600461491b565b61393b565b6103ba61084e36600461491b565b613bad565b61085b613c1e565b61086481613c78565b50565b6108a56040518060400160405280601781526020017f736574436c6f7365466163746f722875696e7432353629000000000000000000815250613d2f565b80670c7d713b49da000010156109195760405162461bcd60e51b815260206004820152602e60248201527f436c6f736520666163746f722067726561746572207468616e206d6178696d7560448201526d369031b637b9b2903330b1ba37b960911b60648201526084015b60405180910390fd5b8066b1a2bc2ec5000011156109875760405162461bcd60e51b815260206004820152602e60248201527f436c6f736520666163746f7220736d616c6c6572207468616e206d696e696d7560448201526d369031b637b9b2903330b1ba37b960911b6064820152608401610910565b60ca80549082905560408051828152602081018490527f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd991015b60405180910390a15050565b6109ee60405180606001604052806028815260200161528060289139613d2f565b828181158015906109fe57508082145b610a3a5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b6044820152606401610910565b610a4382613dcd565b60005b82811015610b3d57848482818110610a6057610a60614f76565b9050602002013560cf6000898985818110610a7d57610a7d614f76565b9050602002016020810190610a92919061491b565b6001600160a01b03168152602081019190915260400160002055868682818110610abe57610abe614f76565b9050602002016020810190610ad3919061491b565b6001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110610b0f57610b0f614f76565b90506020020135604051610b2591815260200190565b60405180910390a2610b3681614fa2565b9050610a46565b50505050505050565b610b51846004613e00565b6001600160a01b038416600090815260cd60205260409020805460ff16610b9657604051635a9a1eb960e11b81526001600160a01b0386166004820152602401610910565b306001600160a01b03851603610c3e57306001600160a01b0316856001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c129190614fbb565b6001600160a01b031614610c3957604051630c73eb0560e01b815260040160405180910390fd5b610d76565b6001600160a01b038416600090815260cd602052604090205460ff16610c8257604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b836001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce49190614fbb565b6001600160a01b0316856001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f9190614fbb565b6001600160a01b031614610d7657604051630c73eb0560e01b815260040160405180910390fd5b6001600160a01b038216600090815260038201602052604090205460ff16610db5578482604051630cdfb2db60e31b8152600401610910929190614fd8565b60d35460005b81811015610b3d57600060d38281548110610dd857610dd8614f76565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b038a8116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015610e2b57600080fd5b505af1158015610e3f573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150610e71908b908990600401614fd8565b600060405180830381600087803b158015610e8b57600080fd5b505af1158015610e9f573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150610ed1908b908a90600401614fd8565b600060405180830381600087803b158015610eeb57600080fd5b505af1158015610eff573d6000803e3d6000fd5b505050505080610f0e90614fa2565b9050610dbb565b610f366040518060600160405280602a81526020016152f9602a9139613d2f565b8382610f4a610f458284614ff2565b613dcd565b60005b82811015610fd85760005b82811015610fc757610fb7898984818110610f7557610f75614f76565b9050602002016020810190610f8a919061491b565b888884818110610f9c57610f9c614f76565b9050602002016020810190610fb19190615011565b87613e2c565b610fc081614fa2565b9050610f58565b50610fd181614fa2565b9050610f4d565b5050505050505050565b6000610ff084613f3a613f6e565b905060d054816000015111156110275760d0548151604051631a451c0f60e21b815260048101929092526024820152604401610910565b6000611047604051806020016040528060cb548152508360400151613fbd565b82519091508110611078578151604051632c1f8ef160e21b8152610910918391600401918252602082015260400190565b8160a0015160000361109d5760405163095bf33360e01b815260040160405180910390fd5b826110ac610f4560028361502c565b60005b818110156112a45760cd60008787848181106110cd576110cd614f76565b90506060020160200160208101906110e5919061491b565b6001600160a01b0316815260208101919091526040016000205460ff166111555785858281811061111857611118614f76565b9050606002016020016020810190611130919061491b565b604051635a9a1eb960e11b81526001600160a01b039091166004820152602401610910565b60cd600087878481811061116b5761116b614f76565b611181926020606090920201908101915061491b565b6001600160a01b0316815260208101919091526040016000205460ff166111ca578585828181106111b4576111b4614f76565b611130926020606090920201908101915061491b565b368686838181106111dd576111dd614f76565b90506060020190508060200160208101906111f8919061491b565b6001600160a01b0316638bbdb6db338a604085013561121a602087018761491b565b60405160e086901b6001600160e01b03191681526001600160a01b0394851660048201529284166024840152604483019190915290911660648201526001608482015260a401600060405180830381600087803b15801561127a57600080fd5b505af115801561128e573d6000803e3d6000fd5b50505050508061129d90614fa2565b90506110af565b506001600160a01b038616600090815260cc602090815260408083208054825181850281018501909352808352919290919083018282801561130f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112f1575b505083519394506000925050505b818110156113be57600061134a84838151811061133c5761133c614f76565b60200260200101518b613fdd565b5091505080156113ad5760405162461bcd60e51b815260206004820152602860248201527f4e6f6e7a65726f20626f72726f772062616c616e6365206166746572206c69716044820152673ab4b230ba34b7b760c11b6064820152608401610910565b506113b781614fa2565b905061131d565b505050505050505050565b6000806000806113de888888886140846140b8565b608081015160a09091015160009a919950975095505050505050565b61141b6040518060600160405280602581526020016152a860259139613d2f565b60d080549082905560408051828152602081018490527eb4f4f153ad7f1397564a8830fef092481e8cf6a2cd3ff04f96d10ba51200a591016109c1565b60008060008061146a85614084613f6e565b608081015160a090910151600097919650945092505050565b60ce818154811061149357600080fd5b6000918252602090912001546001600160a01b0316905081565b6114b5613c1e565b6114be816142ed565b60c980546001600160a01b038381166001600160a01b03198316179092556040519116907fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22906109c19083908590614fd8565b611519613c1e565b6001600160a01b038116600090815260d4602052604090205460ff16156115735760405162461bcd60e51b815260206004820152600e60248201526d616c72656164792065786973747360901b6044820152606401610910565b60d354611584610f4582600161504e565b60d3805460018082019092557f915c3eb987b20e1af620c1403197bf687fb7f18513b3a73fde6e78c7072c41a60180546001600160a01b0319166001600160a01b038516908117909155600090815260d460205260408120805460ff191690921790915560ce54905b8181101561168d57836001600160a01b0316632a869a4d60ce838154811061161757611617614f76565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401600060405180830381600087803b15801561166457600080fd5b505af1158015611678573d6000803e3d6000fd5b505050508061168690614fa2565b90506115ed565b50826001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f09190614fbb565b6001600160a01b0316836001600160a01b03167f066a44d77db1581603d7d8ca1ca494756c0d359c7ffacd9b2c8f78dab7aceae260405160405180910390a3505050565b6001600160a01b038116600090815260cc602090815260408083208054825181850281018501909352808352919290919083018282801561179e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611780575b5050835160c954949550936001600160a01b0316925060009150505b8281101561185957816001600160a01b03166396e85ced8583815181106117e3576117e3614f76565b60200260200101516040518263ffffffff1660e01b815260040161181691906001600160a01b0391909116815260200190565b600060405180830381600087803b15801561183057600080fd5b505af1158015611844573d6000803e3d6000fd5b505050508061185290614fa2565b90506117ba565b5050505050565b6118816040518060600160405280602c81526020016152cd602c9139613d2f565b6001600160a01b038316600090815260cd60205260409020805460ff166118c657604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b670c7d713b49da00008311156118ef576040516302f22cad60e61b815260040160405180910390fd5b670de0b6b3a76400008211156119175760405162f9474b60e61b815260040160405180910390fd5b828210156119375760405162f9474b60e61b815260040160405180910390fd5b82158015906119b1575060c95460405163fc57d4df60e01b81526001600160a01b0386811660048301529091169063fc57d4df90602401602060405180830381865afa15801561198b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119af9190615066565b155b156119d95760405162e52a7d60e41b81526001600160a01b0385166004820152602401610910565b6001810154838114611a375760018201849055604080516001600160a01b0387168152602081018390529081018590527f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59060600160405180910390a15b6002820154838114611a955760028301849055604080516001600160a01b0388168152602081018390529081018590527f9e92c7d5fef69846094f3ddcadcb9402c6ba469c461368714f1cabd8ef48b5919060600160405180910390a15b505050505050565b60008060008061146a85613f3a613f6e565b606060d3805480602002602001604051908101604052809291908181526020018280548015611b0757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611ae9575b5050505050905090565b611b1c846006613e00565b611b27848483614314565b60d35460005b81811015611a9557600060d38281548110611b4a57611b4a614f76565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03898116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015611b9d57600080fd5b505af1158015611bb1573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611be3908a908a90600401614fd8565b600060405180830381600087803b158015611bfd57600080fd5b505af1158015611c11573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611c43908a908990600401614fd8565b600060405180830381600087803b158015611c5d57600080fd5b505af1158015611c71573d6000803e3d6000fd5b505050505080611c8090614fa2565b9050611b2d565b611c8f613c1e565b611c9960006143c2565b565b60655433906001600160a01b03168114611d095760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610910565b610864816143c2565b611d1a613c1e565b610864816143db565b611d2e836001613e00565b611d39838383614314565b60d35460005b8181101561185957600060d38281548110611d5c57611d5c614f76565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03888116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b158015611daf57600080fd5b505af1158015611dc3573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd9150611df59089908990600401614fd8565b600060405180830381600087803b158015611e0f57600080fd5b505af1158015611e23573d6000803e3d6000fd5b505050505080611e3290614fa2565b9050611d3f565b6001600160a01b038116600090815260cc6020908152604080832080548251818502810185019093528083529192909190830182828015611ea357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611e85575b5050835160c954949550933393506001600160a01b03169150600090505b83811015611fde57848181518110611edb57611edb614f76565b60200260200101516001600160a01b031663a6afed956040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f469190615066565b50816001600160a01b03166396e85ced868381518110611f6857611f68614f76565b60200260200101516040518263ffffffff1660e01b8152600401611f9b91906001600160a01b0391909116815260200190565b600060405180830381600087803b158015611fb557600080fd5b505af1158015611fc9573d6000803e3d6000fd5b5050505080611fd790614fa2565b9050611ec1565b50506000611fee85613f3a613f6e565b905060d054816000015111156120255760d0548151604051631a451c0f60e21b815260048101929092526024820152604401610910565b8060a0015160000361204a5760405163095bf33360e01b815260040160405180910390fd5b60408051602080820183528351825282518082018452848401518152835191820190935260cb54815290916000916120829190614477565b9050600061209083836144bf565b90506120b46040518060200160405280670de0b6b3a7640000815250825190511090565b156120df5781518351604051631a451c0f60e21b815260048101929092526024820152604401610910565b60005b868110156113be5760008882815181106120fe576120fe614f76565b60200260200101519050600080612115838d613fdd565b509150915060006121268683613fbd565b905082156121995760405163b2a02ff160e01b81526001600160a01b038b811660048301528e811660248301526044820185905285169063b2a02ff190606401600060405180830381600087803b15801561218057600080fd5b505af1158015612194573d6000803e3d6000fd5b505050505b811561220a5760405163227f37ff60e11b81526001600160a01b038b811660048301528e81166024830152604482018390528516906344fe6ffe90606401600060405180830381600087803b1580156121f157600080fd5b505af1158015612205573d6000803e3d6000fd5b505050505b505050508061221890614fa2565b90506120e2565b6001600160a01b038116600090815260cd602052604081206001015415801561224e575061224e8260026134ba565b80156122c25750670de0b6b3a7640000826001600160a01b031663173b99046040518163ffffffff1660e01b8152600401602060405180830381865afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c09190615066565b145b92915050565b670de0b6b3a764000081101561233a5760405162461bcd60e51b815260206004820152603160248201527f6c69717569646174696f6e20696e63656e746976652073686f756c64206265206044820152700cee4cac2e8cae440e8d0c2dc4062ca627607b1b6064820152608401610910565b6123786040518060400160405280602081526020017f7365744c69717569646174696f6e496e63656e746976652875696e7432353629815250613d2f565b60cb80549082905560408051828152602081018490527faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec131691016109c1565b6001600160a01b038116600090815260cc6020908152604080832080548251818502810185019093528083526060949383018282801561241f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612401575b5093979650505050505050565b606060ce805480602002602001604051908101604052809291908181526020018280548015611b07576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311611ae9575050505050905090565b60d3546060908067ffffffffffffffff8111156124ab576124ab614d74565b60405190808252806020026020018201604052801561250957816020015b6124f6604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b8152602001906001900390816124c95790505b50915060005b818110156126c857600060d3828154811061252c5761252c614f76565b60009182526020808320909101546040805163f7c618c160e01b815290516001600160a01b039092169450849263f7c618c1926004808401938290030181865afa15801561257e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a29190614fbb565b604080516060810182526001600160a01b0380841682529151631d31307360e21b815289831660048201529293509160208301918516906374c4c1cc90602401602060405180830381865afa1580156125ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126239190615066565b8152604051637c05a7c560e01b81526001600160a01b038981166004830152602090920191851690637c05a7c590602401602060405180830381865afa158015612671573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126959190615066565b8152508584815181106126aa576126aa614f76565b60200260200101819052505050806126c190614fa2565b905061250f565b5050919050565b6126da836000613e00565b6001600160a01b038316600090815260cd602052604090205460ff1661271e57604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b038316600090815260d16020526040902054600019811461285f576000846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612780573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a49190615066565b905060006040518060200160405280876001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128159190615066565b9052905060006128268284876144f9565b90508381111561285b5760405163db33be3d60e01b81526001600160a01b038816600482015260248101859052604401610910565b5050505b60d35460005b81811015611a9557600060d3828154811061288257612882614f76565b60009182526020909120015460405163051d1d4f60e11b81526001600160a01b03898116600483015290911691508190630a3a3a9e90602401600060405180830381600087803b1580156128d557600080fd5b505af11580156128e9573d6000803e3d6000fd5b505060405163db7954fd60e01b81526001600160a01b038416925063db7954fd915061291b908a908a90600401614fd8565b600060405180830381600087803b15801561293557600080fd5b505af1158015612949573d6000803e3d6000fd5b50505050508061295890614fa2565b9050612865565b805160609060008167ffffffffffffffff81111561297f5761297f614d74565b6040519080825280602002602001820160405280156129a8578160200160208202803683370190505b50905060005b82811015612a0e5760008582815181106129ca576129ca614f76565b602002602001015190506129de8133614523565b60008383815181106129f2576129f2614f76565b602090810291909101015250612a0781614fa2565b90506129ae565b509392505050565b6000806000612a248661461f565b90506000612a318661461f565b90506000866001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a979190615066565b90506000612ab16040518060200160405280600081525090565b60408051602080820183526000808352835180830185529081528351808301855260cb54815284519283019094528882529192612aed91614477565b9250612b15604051806020016040528088815250604051806020016040528088815250614477565b9150612b2183836144bf565b9050612b2d818b613fbd565b60009d909c509a5050505050505050505050565b612b6a7f00000000000000000000000000000000000000000000000000000000000000006146be565b6001600160a01b038116600090815260cd602052604090205460ff1615612baf5760405163d005ce4760e01b81526001600160a01b0382166004820152602401610910565b806001600160a01b0316633d9ea3a16040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c11919061507f565b612c5d5760405162461bcd60e51b815260206004820152601b60248201527f436f6d7074726f6c6c65723a20496e76616c69642076546f6b656e00000000006044820152606401610910565b6001600160a01b038116600090815260cd60205260408120805460ff19166001908117825581018290556002810191909155612c98826146eb565b60d35460005b81811015612d325760d38181548110612cb957612cb9614f76565b600091825260209091200154604051632a869a4d60e01b81526001600160a01b03868116600483015290911690632a869a4d90602401600060405180830381600087803b158015612d0957600080fd5b505af1158015612d1d573d6000803e3d6000fd5b5050505080612d2b90614fa2565b9050612c9e565b506040516001600160a01b03841681527faf16ad15f9e29d5140e8e81a30a92a755aa8edff3d301053c84392b70c0d09a3906020015b60405180910390a1505050565b612d9660405180606001604052806028815260200161532360289139613d2f565b826000819003612de45760405162461bcd60e51b8152602060048201526019602482015278696e76616c6964206e756d626572206f66206d61726b65747360381b6044820152606401610910565b808214612e2f5760405162461bcd60e51b8152602060048201526019602482015278696e76616c6964206e756d626572206f66206d61726b65747360381b6044820152606401610910565b612e3881613dcd565b60005b81811015611a9557838382818110612e5557612e55614f76565b9050602002013560d16000888885818110612e7257612e72614f76565b9050602002016020810190612e87919061491b565b6001600160a01b03168152602081019190915260400160002055858582818110612eb357612eb3614f76565b9050602002016020810190612ec8919061491b565b6001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f8858584818110612f0457612f04614f76565b90506020020135604051612f1a91815260200190565b60405180910390a2612f2b81614fa2565b9050612e3b565b600054610100900460ff1615808015612f525750600054600160ff909116105b80612f6c5750303b158015612f6c575060005460ff166001145b612fcf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610910565b6000805460ff191660011790558015612ff2576000805461ff0019166101001790555b612ffa6147ba565b613003826147e9565b61300c836143db565b801561304e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001612d68565b505050565b60cc602052816000526040600020818154811061306f57600080fd5b6000918252602090912001546001600160a01b03169150829050565b613096836002613e00565b6001600160a01b038316600090815260cd602052604090205460ff166130da57604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b03808416600090815260cd60209081526040808320938616835260039093019052205460ff1661311e57613114836146be565b61311e3383614523565b61312782611734565b60c95460405163fc57d4df60e01b81526001600160a01b0385811660048301529091169063fc57d4df90602401602060405180830381865afa158015613171573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131959190615066565b6000036131bf5760405162e52a7d60e41b81526001600160a01b0384166004820152602401610910565b6001600160a01b038316600090815260cf602052604090205460001981146132fd576000846001600160a01b03166347bd37186040518163ffffffff1660e01b8152600401602060405180830381865afa158015613221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132459190615066565b90506000856001600160a01b031663bbcac5576040518163ffffffff1660e01b8152600401602060405180830381865afa158015613287573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ab9190615066565b90506000816132ba868561504e565b6132c4919061504e565b9050838111156132f957604051632e649eed60e01b81526001600160a01b038816600482015260248101859052604401610910565b5050505b600061330f84866000866140846140b8565b60a0810151909150156133355760405163bb55fd2760e01b815260040160405180910390fd5b60006040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613380573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a49190615066565b905260d35490915060005b81811015610fd857600060d382815481106133cc576133cc614f76565b600091825260209091200154604051632352607960e01b81526001600160a01b038b811660048301528651602483015290911691508190632352607990604401600060405180830381600087803b15801561342657600080fd5b505af115801561343a573d6000803e3d6000fd5b5050604051636a95ddef60e01b81526001600160a01b038c811660048301528b811660248301528751604483015284169250636a95ddef9150606401600060405180830381600087803b15801561349057600080fd5b505af11580156134a4573d6000803e3d6000fd5b5050505050806134b390614fa2565b90506133af565b6001600160a01b038216600090815260d260205260408120818360088111156134e5576134e561509c565b60088111156134f6576134f661509c565b815260208101919091526040016000205460ff169392505050565b61351c856005613e00565b61352583611734565b6001600160a01b038516600090815260cd602052604090205460ff1661356957604051635a9a1eb960e11b81526001600160a01b0386166004820152602401610910565b6001600160a01b038416600090815260cd602052604090205460ff166135ad57604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b6040516395dd919360e01b81526001600160a01b038481166004830152600091908716906395dd919390602401602060405180830381865afa1580156135f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061361b9190615066565b9050818061362d575061362d8661221f565b1561365957808311156136535760405163e46c155960e01b815260040160405180910390fd5b50611859565b600061366785613f3a613f6e565b905060d05481600001511161369d5760d0548151604051636e61bb0560e11b815260048101929092526024820152604401610910565b8060a001516000036136c25760405163095bf33360e01b815260040160405180910390fd5b60006136de604051806020016040528060ca5481525084613fbd565b905080851115610fd85760405163e46c155960e01b815260040160405180910390fd5b61370c826003613e00565b60c9546040516396e85ced60e01b81526001600160a01b038481166004830152909116906396e85ced90602401600060405180830381600087803b15801561375357600080fd5b505af1158015613767573d6000803e3d6000fd5b505050506001600160a01b038216600090815260cd602052604090205460ff166137af57604051635a9a1eb960e11b81526001600160a01b0383166004820152602401610910565b60d35460005b818110156139355760006040518060200160405280866001600160a01b031663aa5af0fd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382c9190615066565b8152509050600060d3838154811061384657613846614f76565b600091825260209091200154604051632352607960e01b81526001600160a01b0388811660048301528451602483015290911691508190632352607990604401600060405180830381600087803b1580156138a057600080fd5b505af11580156138b4573d6000803e3d6000fd5b5050604051636a95ddef60e01b81526001600160a01b03898116600483015288811660248301528551604483015284169250636a95ddef9150606401600060405180830381600087803b15801561390a57600080fd5b505af115801561391e573d6000803e3d6000fd5b5050505050508061392e90614fa2565b90506137b5565b50505050565b6000613948826008613e00565b816000806139568333613fdd565b50915091508060001461397c5760405163f8a5d66d60e01b815260040160405180910390fd5b613987853384614314565b6001600160a01b038316600090815260cd60209081526040808320338452600381019092529091205460ff166139c35750600095945050505050565b3360009081526003820160209081526040808320805460ff1916905560cc825280832080548251818502810185019093528083529192909190830182828015613a3557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613a17575b5050835193945083925060009150505b82811015613a9757876001600160a01b0316848281518110613a6957613a69614f76565b60200260200101516001600160a01b031603613a8757809150613a97565b613a9081614fa2565b9050613a45565b50818110613aa757613aa76150b2565b33600090815260cc6020526040902080548190613ac6906001906150c8565b81548110613ad657613ad6614f76565b9060005260206000200160009054906101000a90046001600160a01b0316818381548110613b0657613b06614f76565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080805480613b4457613b446150df565b600082815260208120820160001990810180546001600160a01b031916905590910190915560405133916001600160a01b038b16917fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d9190a35060009998505050505050505050565b613bb5613c1e565b606580546001600160a01b0383166001600160a01b03199091168117909155613be66033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b03163314611c995760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610910565b6001600160a01b038116613cdc5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b6064820152608401610910565b609780546001600160a01b038381166001600160a01b03198316179092556040519116907f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0906109c19083908590614fd8565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab90613d629033908690600401615142565b602060405180830381865afa158015613d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613da3919061507f565b905080613dc957333083604051634a3fa29360e01b815260040161091093929190615166565b5050565b61010754811115610864576101075460405163792bfb1b60e11b8152600481019190915260248101829052604401610910565b613e0a82826134ba565b15613dc95781816040516313b3ccb160e31b81526004016109109291906151b4565b6001600160a01b038316600090815260cd602052604090205460ff16613ea55760405162461bcd60e51b815260206004820152602860248201527f63616e6e6f742070617573652061206d61726b65742074686174206973206e6f6044820152671d081b1a5cdd195960c21b6064820152608401610910565b6001600160a01b038316600090815260d2602052604081208291846008811115613ed157613ed161509c565b6008811115613ee257613ee261509c565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d838383604051612d68939291906151d1565b6040805160208082018352600091829052825180820184526001600160a01b0394909416825260cd90522060020154815290565b613fa76040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b613fb6836000806000866140b8565b9392505050565b600080613fca8484614810565b9050613fd581614838565b949350505050565b6040516361bfb47160e11b81526001600160a01b03828116600483015260009182918291829187169063c37f68e290602401608060405180830381865afa15801561402c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061405091906151fe565b919650945092509050801561407c57858560405163015e34d960e61b8152600401610910929190614fd8565b509250925092565b6040805160208082018352600091829052825180820184526001600160a01b0394909416825260cd90522060010154815290565b6140f16040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6001600160a01b038616600090815260cc602090815260408083208054825181850281018501909352808352919290919083018282801561415b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161413d575b505083519394506000925050505b8181101561428f57600083828151811061418557614185614f76565b60200260200101519050600080600061419e848e613fdd565b925092509250600060405180602001604052806141ba8761461f565b815250905060006141d960405180602001604052808581525083614477565b905060006141f36141ed888e63ffffffff16565b83614477565b905061420481878d602001516144f9565b60208c01528a5161421890839088906144f9565b8b5260408b015161422c90849087906144f9565b8b60400181815250508e6001600160a01b0316876001600160a01b0316036142775761425d818f8d606001516144f9565b60608c018190526142719084908f906144f9565b60608c01525b505050505050508061428890614fa2565b9050614169565b506000836060015184604001516142a6919061504e565b905080846020015111156142cd5760208401518190036080850152600060a08501526142e1565b600060808501526020840151810360a08501525b50505095945050505050565b6001600160a01b038116610864576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b038316600090815260cd60205260409020805460ff1661435957604051635a9a1eb960e11b81526001600160a01b0385166004820152602401610910565b6001600160a01b038316600090815260038201602052604090205460ff166143815750505050565b61438a83611734565b600061439c84868560006140846140b8565b60a0810151909150156118595760405163bb55fd2760e01b815260040160405180910390fd5b606580546001600160a01b031916905561086481614850565b6101075481116144385760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b6064820152608401610910565b61010780549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa91016109c1565b6040805160208101909152600081526040518060200160405280670de0b6b3a76400006144ac866000015186600001516148a2565b6144b6919061502c565b90529392505050565b60408051602081019091526000815260405180602001604052806144b66144f28660000151670de0b6b3a76400006148a2565b85516148ae565b6000806145068585614810565b905061451a61451482614838565b846148ba565b95945050505050565b61452e826007613e00565b6001600160a01b038216600090815260cd60205260409020805460ff1661457357604051635a9a1eb960e11b81526001600160a01b0384166004820152602401610910565b6001600160a01b038216600090815260038201602052604090205460ff161561459b57505050565b6001600160a01b0380831660008181526003840160209081526040808320805460ff1916600190811790915560cc835281842080549182018155845291832090910180549488166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a3505050565b60c95460405163fc57d4df60e01b81526001600160a01b038381166004830152600092839291169063fc57d4df90602401602060405180830381865afa15801561466d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146919190615066565b9050806000036122c25760405162e52a7d60e41b81526001600160a01b0384166004820152602401610910565b336001600160a01b03821614610864578033604051634e9383fb60e11b8152600401610910929190614fd8565b60ce5460005b8181101561476457826001600160a01b031660ce828154811061471657614716614f76565b6000918252602090912001546001600160a01b0316036147545760405163d005ce4760e01b81526001600160a01b0384166004820152602401610910565b61475d81614fa2565b90506146f1565b505060ce805460018101825560008290527fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a0180546001600160a01b0319166001600160a01b03841617905554613dc981613dcd565b600054610100900460ff166147e15760405162461bcd60e51b815260040161091090615234565b611c996148c6565b600054610100900460ff1661085b5760405162461bcd60e51b815260040161091090615234565b60408051602081019091526000815260405180602001604052806144b68560000151856148a2565b80516000906122c290670de0b6b3a76400009061502c565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000613fb68284614ff2565b6000613fb6828461502c565b6000613fb6828461504e565b600054610100900460ff166148ed5760405162461bcd60e51b815260040161091090615234565b611c99336143c2565b6001600160a01b038116811461086457600080fd5b8035614916816148f6565b919050565b60006020828403121561492d57600080fd5b8135613fb6816148f6565b60006020828403121561494a57600080fd5b5035919050565b60008083601f84011261496357600080fd5b50813567ffffffffffffffff81111561497b57600080fd5b6020830191508360208260051b850101111561499657600080fd5b9250929050565b600080600080604085870312156149b357600080fd5b843567ffffffffffffffff808211156149cb57600080fd5b6149d788838901614951565b909650945060208701359150808211156149f057600080fd5b506149fd87828801614951565b95989497509550505050565b60008060008060808587031215614a1f57600080fd5b8435614a2a816148f6565b93506020850135614a3a816148f6565b92506040850135614a4a816148f6565b91506060850135614a5a816148f6565b939692955090935050565b801515811461086457600080fd5b600080600080600060608688031215614a8b57600080fd5b853567ffffffffffffffff80821115614aa357600080fd5b614aaf89838a01614951565b90975095506020880135915080821115614ac857600080fd5b50614ad588828901614951565b9094509250506040860135614ae981614a65565b809150509295509295909350565b600080600060408486031215614b0c57600080fd5b8335614b17816148f6565b9250602084013567ffffffffffffffff80821115614b3457600080fd5b818601915086601f830112614b4857600080fd5b813581811115614b5757600080fd5b876020606083028501011115614b6c57600080fd5b6020830194508093505050509250925092565b60008060008060808587031215614b9557600080fd5b8435614ba0816148f6565b93506020850135614bb0816148f6565b93969395505050506040820135916060013590565b600080600060608486031215614bda57600080fd5b8335614be5816148f6565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015614c3b5783516001600160a01b031683529284019291840191600101614c16565b50909695505050505050565b60008060008060808587031215614c5d57600080fd5b8435614c68816148f6565b93506020850135614c78816148f6565b92506040850135614c88816148f6565b9396929550929360600135925050565b600080600060608486031215614cad57600080fd5b8335614cb8816148f6565b92506020840135614cc8816148f6565b929592945050506040919091013590565b60008060408385031215614cec57600080fd5b8235614cf7816148f6565b91506020830135614d07816148f6565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015614d6757815180516001600160a01b0316855286810151878601528501518585015260609093019290850190600101614d2f565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215614d9d57600080fd5b823567ffffffffffffffff80821115614db557600080fd5b818501915085601f830112614dc957600080fd5b813581811115614ddb57614ddb614d74565b8060051b604051601f19603f83011681018181108582111715614e0057614e00614d74565b604052918252848201925083810185019188831115614e1e57600080fd5b938501935b82851015614e4357614e348561490b565b84529385019392850192614e23565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614c3b57835183529284019291840191600101614e6b565b60008060408385031215614e9a57600080fd5b823591506020830135614d07816148f6565b60008060408385031215614ebf57600080fd5b8235614eca816148f6565b946020939093013593505050565b80356009811061491657600080fd5b60008060408385031215614efa57600080fd5b8235614f05816148f6565b9150614f1360208401614ed8565b90509250929050565b600080600080600060a08688031215614f3457600080fd5b8535614f3f816148f6565b94506020860135614f4f816148f6565b93506040860135614f5f816148f6565b9250606086013591506080860135614ae981614a65565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201614fb457614fb4614f8c565b5060010190565b600060208284031215614fcd57600080fd5b8151613fb6816148f6565b6001600160a01b0392831681529116602082015260400190565b600081600019048311821515161561500c5761500c614f8c565b500290565b60006020828403121561502357600080fd5b613fb682614ed8565b60008261504957634e487b7160e01b600052601260045260246000fd5b500490565b6000821982111561506157615061614f8c565b500190565b60006020828403121561507857600080fd5b5051919050565b60006020828403121561509157600080fd5b8151613fb681614a65565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000828210156150da576150da614f8c565b500390565b634e487b7160e01b600052603160045260246000fd5b6000815180845260005b8181101561511b576020818501810151868301820152016150ff565b8181111561512d576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0383168152604060208201819052600090613fd5908301846150f5565b6001600160a01b0384811682528316602082015260606040820181905260009061451a908301846150f5565b600981106151b057634e487b7160e01b600052602160045260246000fd5b9052565b6001600160a01b038316815260408101613fb66020830184615192565b6001600160a01b0384168152606081016151ee6020830185615192565b8215156040830152949350505050565b6000806000806080858703121561521457600080fd5b505082516020840151604085015160609095015191969095509092509050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d297365744d696e4c6971756964617461626c65436f6c6c61746572616c2875696e7432353629736574436f6c6c61746572616c466163746f7228616464726573732c75696e743235362c75696e7432353629736574416374696f6e7350617573656428616464726573735b5d2c75696e743235365b5d2c626f6f6c297365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d29a2646970667358221220f04d34f9fc5387beb487dbd5d16231b8153559f6560d3a8f7481997be14be4d164736f6c634300080d0033", "devdoc": { "author": "Venus", "kind": "dev", @@ -2185,7 +2195,7 @@ "NewPriceOracle(address,address)": { "notice": "Emitted when price oracle is changed" }, - "NewRewardsDistributor(address)": { + "NewRewardsDistributor(address,address)": { "notice": "Emitted when a rewards distributor is added" }, "NewSupplyCap(address,uint256)": { @@ -2204,7 +2214,7 @@ "notice": "Checks if a certain action is paused on a market" }, "addRewardsDistributor(address)": { - "notice": "Add a new RewardsDistributor and initialize it with all markets" + "notice": "Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor contracts with the same rewardToken, and there could be overlaping among them considering the last reward block" }, "allMarkets(uint256)": { "notice": "A list of all markets" @@ -2342,7 +2352,7 @@ "storageLayout": { "storage": [ { - "astId": 244, + "astId": 290, "contract": "contracts/Comptroller.sol:Comptroller", "label": "_initialized", "offset": 0, @@ -2350,7 +2360,7 @@ "type": "t_uint8" }, { - "astId": 247, + "astId": 293, "contract": "contracts/Comptroller.sol:Comptroller", "label": "_initializing", "offset": 1, @@ -2358,7 +2368,7 @@ "type": "t_bool" }, { - "astId": 1351, + "astId": 1397, "contract": "contracts/Comptroller.sol:Comptroller", "label": "__gap", "offset": 0, @@ -2366,7 +2376,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 116, + "astId": 162, "contract": "contracts/Comptroller.sol:Comptroller", "label": "_owner", "offset": 0, @@ -2374,7 +2384,7 @@ "type": "t_address" }, { - "astId": 236, + "astId": 282, "contract": "contracts/Comptroller.sol:Comptroller", "label": "__gap", "offset": 0, @@ -2382,7 +2392,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 25, + "astId": 71, "contract": "contracts/Comptroller.sol:Comptroller", "label": "_pendingOwner", "offset": 0, @@ -2390,7 +2400,7 @@ "type": "t_address" }, { - "astId": 104, + "astId": 150, "contract": "contracts/Comptroller.sol:Comptroller", "label": "__gap", "offset": 0, @@ -2398,15 +2408,15 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 3295, + "astId": 5019, "contract": "contracts/Comptroller.sol:Comptroller", "label": "_accessControlManager", "offset": 0, "slot": "151", - "type": "t_contract(IAccessControlManagerV8)3479" + "type": "t_contract(IAccessControlManagerV8)5203" }, { - "astId": 3300, + "astId": 5024, "contract": "contracts/Comptroller.sol:Comptroller", "label": "__gap", "offset": 0, @@ -2414,15 +2424,15 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 7228, + "astId": 10147, "contract": "contracts/Comptroller.sol:Comptroller", "label": "oracle", "offset": 0, "slot": "201", - "type": "t_contract(ResilientOracleInterface)3497" + "type": "t_contract(ResilientOracleInterface)5262" }, { - "astId": 7231, + "astId": 10150, "contract": "contracts/Comptroller.sol:Comptroller", "label": "closeFactorMantissa", "offset": 0, @@ -2430,7 +2440,7 @@ "type": "t_uint256" }, { - "astId": 7234, + "astId": 10153, "contract": "contracts/Comptroller.sol:Comptroller", "label": "liquidationIncentiveMantissa", "offset": 0, @@ -2438,31 +2448,31 @@ "type": "t_uint256" }, { - "astId": 7241, + "astId": 10160, "contract": "contracts/Comptroller.sol:Comptroller", "label": "accountAssets", "offset": 0, "slot": "204", - "type": "t_mapping(t_address,t_array(t_contract(VToken)17435)dyn_storage)" + "type": "t_mapping(t_address,t_array(t_contract(VToken)20862)dyn_storage)" }, { - "astId": 7247, + "astId": 10166, "contract": "contracts/Comptroller.sol:Comptroller", "label": "markets", "offset": 0, "slot": "205", - "type": "t_mapping(t_address,t_struct(Market)7214_storage)" + "type": "t_mapping(t_address,t_struct(Market)10133_storage)" }, { - "astId": 7252, + "astId": 10171, "contract": "contracts/Comptroller.sol:Comptroller", "label": "allMarkets", "offset": 0, "slot": "206", - "type": "t_array(t_contract(VToken)17435)dyn_storage" + "type": "t_array(t_contract(VToken)20862)dyn_storage" }, { - "astId": 7257, + "astId": 10176, "contract": "contracts/Comptroller.sol:Comptroller", "label": "borrowCaps", "offset": 0, @@ -2470,7 +2480,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7260, + "astId": 10179, "contract": "contracts/Comptroller.sol:Comptroller", "label": "minLiquidatableCollateral", "offset": 0, @@ -2478,7 +2488,7 @@ "type": "t_uint256" }, { - "astId": 7265, + "astId": 10184, "contract": "contracts/Comptroller.sol:Comptroller", "label": "supplyCaps", "offset": 0, @@ -2486,23 +2496,23 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7273, + "astId": 10192, "contract": "contracts/Comptroller.sol:Comptroller", "label": "_actionPaused", "offset": 0, "slot": "210", - "type": "t_mapping(t_address,t_mapping(t_enum(Action)7224,t_bool))" + "type": "t_mapping(t_address,t_mapping(t_enum(Action)10143,t_bool))" }, { - "astId": 7277, + "astId": 10196, "contract": "contracts/Comptroller.sol:Comptroller", "label": "rewardsDistributors", "offset": 0, "slot": "211", - "type": "t_array(t_contract(RewardsDistributor)11868)dyn_storage" + "type": "t_array(t_contract(RewardsDistributor)15116)dyn_storage" }, { - "astId": 7281, + "astId": 10200, "contract": "contracts/Comptroller.sol:Comptroller", "label": "rewardsDistributorExists", "offset": 0, @@ -2510,7 +2520,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 7298, + "astId": 10217, "contract": "contracts/Comptroller.sol:Comptroller", "label": "__gap", "offset": 0, @@ -2518,7 +2528,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 9662, + "astId": 12674, "contract": "contracts/Comptroller.sol:Comptroller", "label": "maxLoopsLimit", "offset": 0, @@ -2526,7 +2536,7 @@ "type": "t_uint256" }, { - "astId": 9667, + "astId": 12679, "contract": "contracts/Comptroller.sol:Comptroller", "label": "__gap", "offset": 0, @@ -2540,14 +2550,14 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_contract(RewardsDistributor)11868)dyn_storage": { - "base": "t_contract(RewardsDistributor)11868", + "t_array(t_contract(RewardsDistributor)15116)dyn_storage": { + "base": "t_contract(RewardsDistributor)15116", "encoding": "dynamic_array", "label": "contract RewardsDistributor[]", "numberOfBytes": "32" }, - "t_array(t_contract(VToken)17435)dyn_storage": { - "base": "t_contract(VToken)17435", + "t_array(t_contract(VToken)20862)dyn_storage": { + "base": "t_contract(VToken)20862", "encoding": "dynamic_array", "label": "contract VToken[]", "numberOfBytes": "32" @@ -2569,37 +2579,37 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(IAccessControlManagerV8)3479": { + "t_contract(IAccessControlManagerV8)5203": { "encoding": "inplace", "label": "contract IAccessControlManagerV8", "numberOfBytes": "20" }, - "t_contract(ResilientOracleInterface)3497": { + "t_contract(ResilientOracleInterface)5262": { "encoding": "inplace", "label": "contract ResilientOracleInterface", "numberOfBytes": "20" }, - "t_contract(RewardsDistributor)11868": { + "t_contract(RewardsDistributor)15116": { "encoding": "inplace", "label": "contract RewardsDistributor", "numberOfBytes": "20" }, - "t_contract(VToken)17435": { + "t_contract(VToken)20862": { "encoding": "inplace", "label": "contract VToken", "numberOfBytes": "20" }, - "t_enum(Action)7224": { + "t_enum(Action)10143": { "encoding": "inplace", "label": "enum ComptrollerStorage.Action", "numberOfBytes": "1" }, - "t_mapping(t_address,t_array(t_contract(VToken)17435)dyn_storage)": { + "t_mapping(t_address,t_array(t_contract(VToken)20862)dyn_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => contract VToken[])", "numberOfBytes": "32", - "value": "t_array(t_contract(VToken)17435)dyn_storage" + "value": "t_array(t_contract(VToken)20862)dyn_storage" }, "t_mapping(t_address,t_bool)": { "encoding": "mapping", @@ -2608,19 +2618,19 @@ "numberOfBytes": "32", "value": "t_bool" }, - "t_mapping(t_address,t_mapping(t_enum(Action)7224,t_bool))": { + "t_mapping(t_address,t_mapping(t_enum(Action)10143,t_bool))": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => mapping(enum ComptrollerStorage.Action => bool))", "numberOfBytes": "32", - "value": "t_mapping(t_enum(Action)7224,t_bool)" + "value": "t_mapping(t_enum(Action)10143,t_bool)" }, - "t_mapping(t_address,t_struct(Market)7214_storage)": { + "t_mapping(t_address,t_struct(Market)10133_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerStorage.Market)", "numberOfBytes": "32", - "value": "t_struct(Market)7214_storage" + "value": "t_struct(Market)10133_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -2629,19 +2639,19 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_enum(Action)7224,t_bool)": { + "t_mapping(t_enum(Action)10143,t_bool)": { "encoding": "mapping", - "key": "t_enum(Action)7224", + "key": "t_enum(Action)10143", "label": "mapping(enum ComptrollerStorage.Action => bool)", "numberOfBytes": "32", "value": "t_bool" }, - "t_struct(Market)7214_storage": { + "t_struct(Market)10133_storage": { "encoding": "inplace", "label": "struct ComptrollerStorage.Market", "members": [ { - "astId": 7205, + "astId": 10124, "contract": "contracts/Comptroller.sol:Comptroller", "label": "isListed", "offset": 0, @@ -2649,7 +2659,7 @@ "type": "t_bool" }, { - "astId": 7207, + "astId": 10126, "contract": "contracts/Comptroller.sol:Comptroller", "label": "collateralFactorMantissa", "offset": 0, @@ -2657,7 +2667,7 @@ "type": "t_uint256" }, { - "astId": 7209, + "astId": 10128, "contract": "contracts/Comptroller.sol:Comptroller", "label": "liquidationThresholdMantissa", "offset": 0, @@ -2665,7 +2675,7 @@ "type": "t_uint256" }, { - "astId": 7213, + "astId": 10132, "contract": "contracts/Comptroller.sol:Comptroller", "label": "accountMembership", "offset": 0, @@ -2687,4 +2697,4 @@ } } } -} +} \ No newline at end of file From 98b514dc49b38c3a37eaf9a8d69081ffdd7d7516 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Fri, 25 Aug 2023 15:23:06 +0100 Subject: [PATCH 15/39] feat: deployed SD Rewards distributor --- .../RewardsDistributor_Stablecoins_2.json | 1278 +++++++++++++++++ ...ewardsDistributor_Stablecoins_2_Proxy.json | 285 ++++ hardhat.config.ts | 8 - 3 files changed, 1563 insertions(+), 8 deletions(-) create mode 100644 deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json create mode 100644 deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json new file mode 100644 index 000000000..812b39cb5 --- /dev/null +++ b/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json @@ -0,0 +1,1278 @@ +{ + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "receipt": { + "to": null, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "transactionIndex": 44, + "gasUsed": "861817", + "logsBloom": "0x00000000020000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000800000000000000000000008000000000000000000000000000000002000001040000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000010000000000080000000000084000000000000800000000000000000000010002000000400000000000000800000000000000000000000000020000000000000000001040000000200000400000000000000000020000000000200000000000000000000000000000800000000000000000000000000", + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1", + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000001251d4ef6bb9f56c8bef7d3a201f00f4c122589" + ], + "data": "0x", + "logIndex": 140, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008bda9f9e1fef0dfd404fef338d9fe4c543d172e1" + ], + "data": "0x", + "logIndex": 141, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", + "logIndex": 142, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 143, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 144, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 145, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + } + ], + "blockNumber": 31163500, + "cumulativeGasUsed": "6625169", + "status": 1, + "byzantium": true + }, + "args": [ + "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0xbe20309400000000000000000000000094c1495cd4c557f1560cbd68eab0d197e62915710000000000000000000000003bc5ac0dfdc871b365d159f728dd1b9a0b5481e800000000000000000000000000000000000000000000000000000000000000640000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571", + "0x3BC5AC0dFdC871B365d159f728dd1B9A0B5481E8", + 100, + "0x4788629ABc6cFCA10F9f969efdEAa1cF70c23555" + ] + }, + "implementation": "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json new file mode 100644 index 000000000..c8c13d017 --- /dev/null +++ b/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json @@ -0,0 +1,285 @@ +{ + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "receipt": { + "to": null, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "transactionIndex": 44, + "gasUsed": "861817", + "logsBloom": "0x00000000020000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000800000000000000000000008000000000000000000000000000000002000001040000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000010000000000080000000000084000000000000800000000000000000000010002000000400000000000000800000000000000000000000000020000000000000000001040000000200000400000000000000000020000000000200000000000000000000000000000800000000000000000000000000", + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1", + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000001251d4ef6bb9f56c8bef7d3a201f00f4c122589" + ], + "data": "0x", + "logIndex": 140, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008bda9f9e1fef0dfd404fef338d9fe4c543d172e1" + ], + "data": "0x", + "logIndex": 141, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", + "logIndex": 142, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 143, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 144, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + }, + { + "transactionIndex": 44, + "blockNumber": 31163500, + "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 145, + "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + } + ], + "blockNumber": 31163500, + "cumulativeGasUsed": "6625169", + "status": 1, + "byzantium": true + }, + "args": [ + "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0xbe20309400000000000000000000000094c1495cd4c557f1560cbd68eab0d197e62915710000000000000000000000003bc5ac0dfdc871b365d159f728dd1b9a0b5481e800000000000000000000000000000000000000000000000000000000000000640000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index 39e9a9548..d5a587f9a 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -73,7 +73,6 @@ task("addMarket", "Add a market to an existing pool") task("deployComptroller", "Deploys a Comptroller Implementation") .addParam("contractName", "Contract name, later we can load contracts by name") .addParam("poolRegistry", "Address of PoolRegistry Contract") - .addParam("verify", "Verify the contract") .setAction(async (taskArgs, hre) => { const { deployer } = await hre.getNamedAccounts(); const Comptroller: DeployResult = await hre.deployments.deploy(taskArgs.contractName, { @@ -83,13 +82,6 @@ task("deployComptroller", "Deploys a Comptroller Implementation") log: true, }); - if (taskArgs.verify == "true") { - await hre.run("verify:verify", { - address: Comptroller.address, - constructorArguments: [taskArgs.poolRegistry], - }); - } - console.log("Comptroller implementation deployed with address: " + Comptroller.address); }); From 554d556c2cfa4682c89323f2e738f18b671470d0 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Fri, 25 Aug 2023 15:26:45 +0100 Subject: [PATCH 16/39] chore: fix lint --- deploy/012-transfer-pools-ownership.ts | 2 +- deployments/bscmainnet.json | 2 +- deployments/bscmainnet/ComptrollerImpl.json | 10 +++------- .../RewardsDistributor_Stablecoins_1.json | 18 +++++------------- ...RewardsDistributor_Stablecoins_1_Proxy.json | 18 +++++------------- .../RewardsDistributor_Stablecoins_2.json | 18 +++++------------- ...RewardsDistributor_Stablecoins_2_Proxy.json | 18 +++++------------- deployments/bsctestnet.json | 2 +- hardhat.config.ts | 3 +-- 9 files changed, 27 insertions(+), 64 deletions(-) diff --git a/deploy/012-transfer-pools-ownership.ts b/deploy/012-transfer-pools-ownership.ts index c37ffa125..252de0598 100644 --- a/deploy/012-transfer-pools-ownership.ts +++ b/deploy/012-transfer-pools-ownership.ts @@ -2,7 +2,7 @@ import { ethers, getNamedAccounts } from "hardhat"; import { DeployFunction } from "hardhat-deploy/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { PoolConfig, RewardConfig, getConfig } from "../helpers/deploymentConfig"; +import { PoolConfig, getConfig } from "../helpers/deploymentConfig"; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployer } = await getNamedAccounts(); diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index fccb083c8..1e089a136 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -36493,4 +36493,4 @@ ] } } -} \ No newline at end of file +} diff --git a/deployments/bscmainnet/ComptrollerImpl.json b/deployments/bscmainnet/ComptrollerImpl.json index 57bc9b5d1..7fb7f919a 100644 --- a/deployments/bscmainnet/ComptrollerImpl.json +++ b/deployments/bscmainnet/ComptrollerImpl.json @@ -1680,9 +1680,7 @@ "blockNumber": 31163370, "transactionHash": "0x404572cb1f8beb703369f9e8a142e4c7e97d1119d63b487ec6c8f09aa7e920ec", "address": "0x17a6ac4f7f01387303deB1D78f01aC0A0C1a75b0", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", "logIndex": 336, "blockHash": "0x7aeda808ef0049041c57e712e2cbb1212f5e5be92493692c9aa7d508ae47950a" @@ -1693,9 +1691,7 @@ "status": 1, "byzantium": true }, - "args": [ - "0x9F7b01A536aFA00EF10310A162877fd792cD0666" - ], + "args": ["0x9F7b01A536aFA00EF10310A162877fd792cD0666"], "numDeployments": 1, "solcInputHash": "8e6073e680dfb04e9a49d04e0bdfc250", "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"ActionPaused\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"cap\",\"type\":\"uint256\"}],\"name\":\"BorrowCapExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedLessThanOrEqualTo\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"CollateralExceedsThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ComptrollerMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"collateralToSeize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableCollateral\",\"type\":\"uint256\"}],\"name\":\"InsufficientCollateral\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientShortfall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCollateralFactor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLiquidationThreshold\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"}],\"name\":\"MarketAlreadyListed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"MarketNotCollateral\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"}],\"name\":\"MarketNotListed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopsLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredLoops\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedGreaterThan\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"MinimalCollateralViolated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonzeroBorrowBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"PriceError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"SnapshotError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"cap\",\"type\":\"uint256\"}],\"name\":\"SupplyCapExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooMuchRepay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"calledContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"methodSignature\",\"type\":\"string\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"expectedSender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"actualSender\",\"type\":\"address\"}],\"name\":\"UnexpectedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"pauseState\",\"type\":\"bool\"}],\"name\":\"ActionPausedMarket\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketExited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketSupported\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMaxLoopsLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newmaxLoopsLimit\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBorrowCap\",\"type\":\"uint256\"}],\"name\":\"NewBorrowCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCloseFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCloseFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCollateralFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCollateralFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldLiquidationIncentiveMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"NewLiquidationIncentive\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldLiquidationThresholdMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLiquidationThresholdMantissa\",\"type\":\"uint256\"}],\"name\":\"NewLiquidationThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMinLiquidatableCollateral\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMinLiquidatableCollateral\",\"type\":\"uint256\"}],\"name\":\"NewMinLiquidatableCollateral\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"oldPriceOracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"newPriceOracle\",\"type\":\"address\"}],\"name\":\"NewPriceOracle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardsDistributor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"}],\"name\":\"NewRewardsDistributor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSupplyCap\",\"type\":\"uint256\"}],\"name\":\"NewSupplyCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerStorage.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract RewardsDistributor\",\"name\":\"_rewardsDistributor\",\"type\":\"address\"}],\"name\":\"addRewardsDistributor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"checkMembership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"vTokens\",\"type\":\"address[]\"}],\"name\":\"enterMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenAddress\",\"type\":\"address\"}],\"name\":\"exitMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllMarkets\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAssetsIn\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getBorrowingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenModify\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"getHypotheticalAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shortfall\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRewardDistributors\",\"outputs\":[{\"internalType\":\"contract RewardsDistributor[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"getRewardsByMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"supplySpeed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowSpeed\",\"type\":\"uint256\"}],\"internalType\":\"struct ComptrollerStorage.RewardSpeeds[]\",\"name\":\"rewardSpeeds\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"healAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accessControlManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isComptroller\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"isDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"isMarketListed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract VToken\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ComptrollerStorage.LiquidationOrder[]\",\"name\":\"orders\",\"type\":\"tuple[]\"}],\"name\":\"liquidateAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateCalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokensToSeize\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidationThresholdMantissa\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLoopsLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minLiquidatableCollateral\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"preBorrowHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"skipLiquidityCheck\",\"type\":\"bool\"}],\"name\":\"preLiquidateHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"mintAmount\",\"type\":\"uint256\"}],\"name\":\"preMintHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"preRedeemHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"}],\"name\":\"preRepayHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"seizerContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"}],\"name\":\"preSeizeHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"preTransferHook\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"marketsList\",\"type\":\"address[]\"},{\"internalType\":\"enum ComptrollerStorage.Action[]\",\"name\":\"actionsList\",\"type\":\"uint8[]\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"setActionsPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"setCloseFactor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLiquidationThresholdMantissa\",\"type\":\"uint256\"}],\"name\":\"setCollateralFactor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"setLiquidationIncentive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newBorrowCaps\",\"type\":\"uint256[]\"}],\"name\":\"setMarketBorrowCaps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newSupplyCaps\",\"type\":\"uint256[]\"}],\"name\":\"setMarketSupplyCaps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setMaxLoopsLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newMinLiquidatableCollateral\",\"type\":\"uint256\"}],\"name\":\"setMinLiquidatableCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"setPriceOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"supportMarket\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action to check\",\"market\":\"vToken address\"},\"returns\":{\"_0\":\"paused True if the action is paused otherwise false\"}},\"addRewardsDistributor(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewRewardsDistributor with distributor address\",\"details\":\"Only callable by the admin\",\"params\":{\"_rewardsDistributor\":\"Address of the RewardDistributor contract to add\"}},\"checkMembership(address,address)\":{\"params\":{\"account\":\"The address of the account to check\",\"vToken\":\"The vToken to check\"},\"returns\":{\"_0\":\"True if the account is in the market specified, otherwise false.\"}},\"constructor\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"params\":{\"poolRegistry_\":\"Pool registry address\"}},\"enterMarkets(address[])\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if entering any of the markets is pausedMarketNotListed error is thrown if any of the markets is not listed\",\"custom:event\":\"MarketEntered is emitted for each market on success\",\"params\":{\"vTokens\":\"The list of addresses of the vToken markets to be enabled\"},\"returns\":{\"_0\":\"errors An array of NO_ERROR for compatibility with Venus core tooling\"}},\"exitMarket(address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if exiting the market is pausedNonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if exiting the market would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"custom:event\":\"MarketExited is emitted on success\",\"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\"},\"returns\":{\"_0\":\"error Always NO_ERROR for compatibility with Venus core tooling\"}},\"getAccountLiquidity(address)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"params\":{\"account\":\"The account get liquidity for\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Account liquidity in excess of liquidation threshold requirements,\",\"shortfall\":\"Account shortfall below liquidation threshold requirements\"}},\"getAllMarkets()\":{\"details\":\"The automatic getter may be used to access an individual market.\",\"returns\":{\"_0\":\"markets The list of market addresses\"}},\"getAssetsIn(address)\":{\"params\":{\"account\":\"The address of the account to pull assets for\"},\"returns\":{\"_0\":\"A list with the assets the account has entered\"}},\"getBorrowingPower(address)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"params\":{\"account\":\"The account get liquidity for\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Account liquidity in excess of collateral requirements,\",\"shortfall\":\"Account shortfall below collateral requirements\"}},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"details\":\"The interface of this function is intentionally kept compatible with Compound and Venus Core\",\"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\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"liquidity\":\"Hypothetical account liquidity in excess of collateral requirements,\",\"shortfall\":\"Hypothetical account shortfall below collateral requirements\"}},\"getRewardDistributors()\":{\"returns\":{\"_0\":\"Array of RewardDistributor addresses\"}},\"getRewardsByMarket(address)\":{\"params\":{\"vToken\":\"The vToken to get the reward speeds for\"},\"returns\":{\"rewardSpeeds\":\"Array of total supply and borrow speeds and reward token for all reward distributors\"}},\"healAccount(address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"CollateralExceedsThreshold error is thrown when the collateral is too big for healingSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"user\":\"account to heal\"}},\"initialize(uint256,address)\":{\"params\":{\"accessControlManager\":\"Access control manager contract address\",\"loopLimit\":\"Limit for the loops can iterate to avoid the DOS\"}},\"isComptroller()\":{\"returns\":{\"_0\":\"Always true\"}},\"isDeprecated(address)\":{\"details\":\"All borrows in a deprecated vToken market can be immediately liquidated\",\"params\":{\"vToken\":\"The market to check if deprecated\"},\"returns\":{\"_0\":\"deprecated True if the given vToken market has been deprecated\"}},\"isMarketListed(address)\":{\"params\":{\"vToken\":\"vToken Address for the market to check\"},\"returns\":{\"_0\":\"listed True if listed otherwise false\"}},\"liquidateAccount(address,(address,address,uint256)[])\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidationInsufficientCollateral error is thrown when there is not enough collateral to cover the debtSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"borrower\":\"the borrower address\",\"orders\":\"an array of liquidation orders\"}},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"custom:error\":\"PriceError if the oracle returns an invalid price\",\"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\"},\"returns\":{\"error\":\"Always NO_ERROR for compatibility with Venus core tooling\",\"tokensToSeize\":\"Number of vTokenCollateral tokens to be seized in a liquidation\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"preLiquidateHook(address,address,address,uint256,bool)\":{\"custom:error\":\"ActionPaused error is thrown if liquidations are paused in this marketMarketNotListed error is thrown if either collateral or borrowed token is not listedTooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factorMinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidationsInsufficientShortfall is thrown when trying to liquidate a healthy accountSnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"params\":{\"borrower\":\"The address of the borrower\",\"repayAmount\":\"The amount of underlying being repaid\",\"skipLiquidityCheck\":\"Allows the borrow to be liquidated regardless of the account liquidity\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"preMintHook(address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if supplying to this market is pausedMarketNotListed error is thrown when the market is not listedSupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\",\"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\"}},\"preRedeemHook(address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if withdrawals are paused in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"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\"}},\"preRepayHook(address,address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if repayments are paused in this marketMarketNotListed error is thrown when the market is not listed\",\"params\":{\"borrower\":\"The account which would borrowed the asset\",\"vToken\":\"The market to verify the repay against\"}},\"preSeizeHook(address,address,address,address)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if seizing this type of collateral is pausedMarketNotListed error is thrown if either collateral or borrowed token is not listedComptrollerMismatch error is when seizer contract or seized asset belong to different pools\",\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizerContract\":\"Contract that tries to seize the asset (either borrowed vToken or Comptroller)\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"preTransferHook(address,address,address,uint256)\":{\"custom:access\":\"Not restricted\",\"custom:error\":\"ActionPaused error is thrown if withdrawals are paused in this marketMarketNotListed error is thrown when the market is not listedInsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvencySnapshotError is thrown if some vToken fails to return the account's supply and borrowsPriceError is thrown if the oracle returns an incorrect price for some asset\",\"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\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewAccessControlManager event\",\"details\":\"Admin function to set address of AccessControlManager\",\"params\":{\"accessControlManager_\":\"The new address of the AccessControlManager\"}},\"setActionsPaused(address[],uint8[],bool)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"actionsList\":\"List of action ids to pause/unpause\",\"marketsList\":\"Markets to pause/unpause the actions on\",\"paused\":\"The new paused state (true=paused, false=unpaused)\"}},\"setCloseFactor(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:event\":\"Emits NewCloseFactor on success\",\"params\":{\"newCloseFactorMantissa\":\"New close factor, scaled by 1e18\"}},\"setCollateralFactor(address,uint256,uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:error\":\"MarketNotListed error is thrown when the market is not listedInvalidCollateralFactor error is thrown when collateral factor is too highInvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factorPriceError is thrown when the oracle returns an invalid price for the asset\",\"custom:event\":\"Emits NewCollateralFactor when collateral factor is updated and NewLiquidationThreshold when liquidation threshold is updated\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newCollateralFactorMantissa\":\"The new collateral factor, scaled by 1e18\",\"newLiquidationThresholdMantissa\":\"The new liquidation threshold, scaled by 1e18\",\"vToken\":\"The market to set the factor on\"}},\"setLiquidationIncentive(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"custom:event\":\"Emits NewLiquidationIncentive on success\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newLiquidationIncentiveMantissa\":\"New liquidationIncentive scaled by 1e18\"}},\"setMarketBorrowCaps(address[],uint256[])\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManagerA borrow cap of type(uint256).max corresponds to unlimited borrowing.Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed until the total borrows amount goes below the new borrow cap\",\"params\":{\"newBorrowCaps\":\"The new borrow cap values in underlying to be set. A value of type(uint256).max corresponds to unlimited borrowing.\",\"vTokens\":\"The addresses of the markets (tokens) to change the borrow caps for\"}},\"setMarketSupplyCaps(address[],uint256[])\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManagerA supply cap of type(uint256).max corresponds to unlimited supply.Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed until the total supplies amount goes below the new supply cap\",\"params\":{\"newSupplyCaps\":\"The new supply cap values in underlying to be set. A value of type(uint256).max corresponds to unlimited supply.\",\"vTokens\":\"The addresses of the markets (tokens) to change the supply caps for\"}},\"setMaxLoopsLimit(uint256)\":{\"params\":{\"limit\":\"Limit for the max loops can execute at a time\"}},\"setMinLiquidatableCollateral(uint256)\":{\"custom:access\":\"Controlled by AccessControlManager\",\"details\":\"This function is restricted by the AccessControlManager\",\"params\":{\"newMinLiquidatableCollateral\":\"The new min liquidatable collateral (in USD).\"}},\"setPriceOracle(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when the new oracle address is zero\",\"custom:event\":\"Emits NewPriceOracle on success\",\"details\":\"Only callable by the admin\",\"params\":{\"newOracle\":\"Address of the new price oracle to set\"}},\"supportMarket(address)\":{\"custom:access\":\"Only PoolRegistry\",\"custom:error\":\"MarketAlreadyListed is thrown if the market is already listed in this pool\",\"details\":\"Only callable by the PoolRegistry\",\"params\":{\"vToken\":\"The address of the market (token) to list\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"updatePrices(address)\":{\"params\":{\"account\":\"Address of the account to get associated tokens with\"}}},\"stateVariables\":{\"poolRegistry\":{\"custom:oz-upgrades-unsafe-allow\":\"state-variable-immutable\"}},\"title\":\"Comptroller\",\"version\":1},\"userdoc\":{\"errors\":{\"ActionPaused(address,uint8)\":[{\"notice\":\"Thrown when trying to perform an action that is paused\"}],\"BorrowCapExceeded(address,uint256)\":[{\"notice\":\"Thrown if the borrow cap is exceeded\"}],\"ComptrollerMismatch()\":[{\"notice\":\"Thrown when a market has an unexpected comptroller\"}],\"InsufficientLiquidity()\":[{\"notice\":\"Thrown when the account doesn't have enough liquidity to redeem or borrow\"}],\"InsufficientShortfall()\":[{\"notice\":\"Thrown when trying to liquidate a healthy account\"}],\"InvalidCollateralFactor()\":[{\"notice\":\"Thrown when collateral factor exceeds the upper bound\"}],\"InvalidLiquidationThreshold()\":[{\"notice\":\"Thrown when liquidation threshold exceeds the collateral factor\"}],\"MarketAlreadyListed(address)\":[{\"notice\":\"Thrown when trying to add a market that is already listed\"}],\"MarketNotCollateral(address,address)\":[{\"notice\":\"Thrown when user is not member of market\"}],\"MarketNotListed(address)\":[{\"notice\":\"Thrown when the market is not listed\"}],\"MaxLoopsLimitExceeded(uint256,uint256)\":[{\"notice\":\"Thrown an error on maxLoopsLimit exceeds for any loop\"}],\"MinimalCollateralViolated(uint256,uint256)\":[{\"notice\":\"Thrown during the liquidation if user's total collateral amount is lower than a predefined threshold. In this case only batch liquidations (either liquidateAccount or healAccount) are available.\"}],\"NonzeroBorrowBalance()\":[{\"notice\":\"Thrown if the user is trying to exit a market in which they have an outstanding debt\"}],\"PriceError(address)\":[{\"notice\":\"Thrown when the oracle returns an invalid price for some asset\"}],\"SnapshotError(address,address)\":[{\"notice\":\"Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\"}],\"SupplyCapExceeded(address,uint256)\":[{\"notice\":\"Thrown if the supply cap is exceeded\"}],\"TooMuchRepay()\":[{\"notice\":\"Thrown when trying to repay more than allowed by close factor\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"Thrown when the action is prohibited by AccessControlManager\"}],\"UnexpectedSender(address,address)\":[{\"notice\":\"Thrown when the action is only available to specific sender, but the real sender was different\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"ActionPausedMarket(address,uint8,bool)\":{\"notice\":\"Emitted when an action is paused on a market\"},\"MarketEntered(address,address)\":{\"notice\":\"Emitted when an account enters a market\"},\"MarketExited(address,address)\":{\"notice\":\"Emitted when an account exits a market\"},\"MarketSupported(address)\":{\"notice\":\"Emitted when a market is supported\"},\"MaxLoopsLimitUpdated(uint256,uint256)\":{\"notice\":\"Emitted when max loops limit is set\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when access control manager contract address is changed\"},\"NewBorrowCap(address,uint256)\":{\"notice\":\"Emitted when borrow cap for a vToken is changed\"},\"NewCloseFactor(uint256,uint256)\":{\"notice\":\"Emitted when close factor is changed by admin\"},\"NewCollateralFactor(address,uint256,uint256)\":{\"notice\":\"Emitted when a collateral factor is changed by admin\"},\"NewLiquidationIncentive(uint256,uint256)\":{\"notice\":\"Emitted when liquidation incentive is changed by admin\"},\"NewLiquidationThreshold(address,uint256,uint256)\":{\"notice\":\"Emitted when liquidation threshold is changed by admin\"},\"NewMinLiquidatableCollateral(uint256,uint256)\":{\"notice\":\"Emitted when the collateral threshold (in USD) for non-batch liquidations is changed\"},\"NewPriceOracle(address,address)\":{\"notice\":\"Emitted when price oracle is changed\"},\"NewRewardsDistributor(address,address)\":{\"notice\":\"Emitted when a rewards distributor is added\"},\"NewSupplyCap(address,uint256)\":{\"notice\":\"Emitted when supply cap for a vToken is changed\"}},\"kind\":\"user\",\"methods\":{\"accessControlManager()\":{\"notice\":\"Returns the address of the access control manager contract\"},\"accountAssets(address,uint256)\":{\"notice\":\"Per-account mapping of \\\"assets you are in\\\"\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"addRewardsDistributor(address)\":{\"notice\":\"Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\"},\"allMarkets(uint256)\":{\"notice\":\"A list of all markets\"},\"borrowCaps(address)\":{\"notice\":\"Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\"},\"checkMembership(address,address)\":{\"notice\":\"Returns whether the given account is entered in a given market\"},\"closeFactorMantissa()\":{\"notice\":\"Multiplier used to calculate the maximum repayAmount when liquidating a borrow\"},\"enterMarkets(address[])\":{\"notice\":\"Add assets to be included in account liquidity calculation; enabling them to be used as collateral\"},\"exitMarket(address)\":{\"notice\":\"Removes asset from sender's account liquidity calculation; disabling them as collateral\"},\"getAccountLiquidity(address)\":{\"notice\":\"Determine the current account liquidity with respect to liquidation threshold requirements\"},\"getAllMarkets()\":{\"notice\":\"Return all of the markets\"},\"getAssetsIn(address)\":{\"notice\":\"Returns the assets an account has entered\"},\"getBorrowingPower(address)\":{\"notice\":\"Determine the current account liquidity with respect to collateral requirements\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"notice\":\"Determine what the account liquidity would be if the given amounts were redeemed/borrowed\"},\"getRewardDistributors()\":{\"notice\":\"Return all reward distributors for this pool\"},\"getRewardsByMarket(address)\":{\"notice\":\"Returns reward speed given a vToken\"},\"healAccount(address)\":{\"notice\":\"Seizes all the remaining collateral, makes msg.sender repay the existing borrows, and treats the rest of the debt as bad debt (for each market). The sender has to repay a certain percentage of the debt, computed as collateral / (borrows * liquidationIncentive).\"},\"isComptroller()\":{\"notice\":\"A marker method that returns true for a valid Comptroller contract\"},\"isDeprecated(address)\":{\"notice\":\"Check if a vToken market has been deprecated\"},\"isMarketListed(address)\":{\"notice\":\"Check if a market is marked as listed (active)\"},\"liquidateAccount(address,(address,address,uint256)[])\":{\"notice\":\"Liquidates all borrows of the borrower. Callable only if the collateral is less than a predefined threshold, and the account collateral can be seized to cover all borrows. If the collateral is higher than the threshold, use regular liquidations. If the collateral is below the threshold, and the account is insolvent, use healAccount.\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"liquidationIncentiveMantissa()\":{\"notice\":\"Multiplier representing the discount on collateral that a liquidator receives\"},\"markets(address)\":{\"notice\":\"Official mapping of vTokens -> Market metadata\"},\"minLiquidatableCollateral()\":{\"notice\":\"Minimal collateral required for regular (non-batch) liquidations\"},\"oracle()\":{\"notice\":\"Oracle which gives the price of any given asset\"},\"preBorrowHook(address,address,uint256)\":{\"notice\":\"disable-eslint\"},\"preLiquidateHook(address,address,address,uint256,bool)\":{\"notice\":\"Checks if the liquidation should be allowed to occur\"},\"preMintHook(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to mint tokens in the given market\"},\"preRedeemHook(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to redeem tokens in the given market\"},\"preRepayHook(address,address)\":{\"notice\":\"Checks if the account should be allowed to repay a borrow in the given market\"},\"preSeizeHook(address,address,address,address)\":{\"notice\":\"Checks if the seizing of assets should be allowed to occur\"},\"preTransferHook(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to transfer tokens in the given market\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of AccessControlManager\"},\"setActionsPaused(address[],uint8[],bool)\":{\"notice\":\"Pause/unpause specified actions\"},\"setCloseFactor(uint256)\":{\"notice\":\"Sets the closeFactor to use when liquidating borrows\"},\"setCollateralFactor(address,uint256,uint256)\":{\"notice\":\"Sets the collateralFactor for a market\"},\"setLiquidationIncentive(uint256)\":{\"notice\":\"Sets liquidationIncentive\"},\"setMarketBorrowCaps(address[],uint256[])\":{\"notice\":\"Set the given borrow caps for the given vToken markets. 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 markets. Supply that brings total Supply to or above supply cap will revert.\"},\"setMaxLoopsLimit(uint256)\":{\"notice\":\"Set the for loop iteration limit to avoid DOS\"},\"setMinLiquidatableCollateral(uint256)\":{\"notice\":\"Set the given collateral threshold for non-batch liquidations. Regular liquidations will fail if the collateral amount is less than this threshold. Liquidators should use batch operations like liquidateAccount or healAccount.\"},\"setPriceOracle(address)\":{\"notice\":\"Sets a new price oracle for the Comptroller\"},\"supplyCaps(address)\":{\"notice\":\"Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\"},\"supportMarket(address)\":{\"notice\":\"Add the market to the markets mapping and set it as listed\"},\"updatePrices(address)\":{\"notice\":\"Update the prices of all the tokens associated with the provided account\"}},\"notice\":\"The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating, and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow, as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed the `minLiquidatableCollateral` for the `Comptroller`: - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool. - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic verifying that the repay amount does not exceed the close factor.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller.sol\":\"Comptroller\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x40031b19684ca0c912e794d08c2c0b0d8be77d3c1bdc937830a0658eff899650\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 badDebt = VToken(vToken).badDebt();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x73fdb4e4b2a2cfec75b0ef5a19491c4136a7953e1239989fb77ed26c1b7a77ac\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n // The block number at which to stop rewards\\n uint32 lastRewardingBlock;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n /// @notice Emitted when a reward token last rewarding block for supply is updated\\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n */\\n function setLastRewardingBlocks(\\n VToken[] calldata vTokens,\\n uint32[] calldata supplyLastRewardingBlocks,\\n uint32[] calldata borrowLastRewardingBlocks\\n ) external {\\n _checkAccessAllowed(\\\"setLastRewardingBlock(address[],uint32[],uint32[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ) {\\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for a single market.\\n * @param vToken market's whose reward token last rewarding block to be updated\\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n */\\n function _setLastRewardingBlock(\\n VToken vToken,\\n uint32 supplyLastRewardingBlock,\\n uint32 borrowLastRewardingBlock\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n uint256 blockNumber = getBlockNumber();\\n\\n require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n require(\\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n require(\\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n\\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n }\\n\\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\\n blockNumber = supplyState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\\n blockNumber = borrowState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0x0e5bede4edc4346e689de0adcf98dc9642feb55d44c1916715741c5937a34d52\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", @@ -2697,4 +2693,4 @@ } } } -} \ No newline at end of file +} diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_1.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_1.json index f6cf23abb..77f724f04 100644 --- a/deployments/bscmainnet/RewardsDistributor_Stablecoins_1.json +++ b/deployments/bscmainnet/RewardsDistributor_Stablecoins_1.json @@ -1172,9 +1172,7 @@ "blockNumber": 30728477, "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", "logIndex": 245, "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" @@ -1184,9 +1182,7 @@ "blockNumber": 30728477, "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 246, "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" @@ -1196,9 +1192,7 @@ "blockNumber": 30728477, "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 247, "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" @@ -1208,9 +1202,7 @@ "blockNumber": 30728477, "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", "logIndex": 248, "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" @@ -1275,4 +1267,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_1_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_1_Proxy.json index 24ecc85bf..3eb4e275f 100644 --- a/deployments/bscmainnet/RewardsDistributor_Stablecoins_1_Proxy.json +++ b/deployments/bscmainnet/RewardsDistributor_Stablecoins_1_Proxy.json @@ -189,9 +189,7 @@ "blockNumber": 30728477, "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", "logIndex": 245, "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" @@ -201,9 +199,7 @@ "blockNumber": 30728477, "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 246, "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" @@ -213,9 +209,7 @@ "blockNumber": 30728477, "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 247, "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" @@ -225,9 +219,7 @@ "blockNumber": 30728477, "transactionHash": "0x722029139420abfca0a48f179a3954e3c5a42d557a09484ecc34a69d46fe194f", "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", "logIndex": 248, "blockHash": "0x6cec23c16a3d5f8edd2d6465259e2cb23e63c0d0f4d8d9d1f63bb5677be85f9b" @@ -282,4 +274,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json index 812b39cb5..4c20676c1 100644 --- a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json +++ b/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json @@ -1172,9 +1172,7 @@ "blockNumber": 31163500, "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", "logIndex": 142, "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" @@ -1184,9 +1182,7 @@ "blockNumber": 31163500, "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 143, "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" @@ -1196,9 +1192,7 @@ "blockNumber": 31163500, "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 144, "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" @@ -1208,9 +1202,7 @@ "blockNumber": 31163500, "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", "logIndex": 145, "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" @@ -1275,4 +1267,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json b/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json index c8c13d017..a07501702 100644 --- a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json +++ b/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json @@ -189,9 +189,7 @@ "blockNumber": 31163500, "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", "logIndex": 142, "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" @@ -201,9 +199,7 @@ "blockNumber": 31163500, "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 143, "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" @@ -213,9 +209,7 @@ "blockNumber": 31163500, "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 144, "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" @@ -225,9 +219,7 @@ "blockNumber": 31163500, "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", "logIndex": 145, "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" @@ -282,4 +274,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bsctestnet.json b/deployments/bsctestnet.json index e4a8f67ae..faa4bf47d 100644 --- a/deployments/bsctestnet.json +++ b/deployments/bsctestnet.json @@ -49012,4 +49012,4 @@ ] } } -} \ No newline at end of file +} diff --git a/hardhat.config.ts b/hardhat.config.ts index d5a587f9a..64ef887ec 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -15,7 +15,6 @@ import "solidity-coverage"; import "solidity-docgen"; import { convertToUnit } from "./helpers/utils"; -import { run } from "hardhat"; dotenv.config(); @@ -202,7 +201,7 @@ const config: HardhatUserConfig = { apiKey: { bscmainnet: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", testnet: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", - } + }, }, paths: { tests: "./tests", From 2aedd92714a101d2ce8d255ab24051049d647ed3 Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Fri, 25 Aug 2023 18:35:05 +0100 Subject: [PATCH 17/39] fix: deployed reward distributors for mainnet and testnet --- ...RewardsDistributor_LiquidStakedBNB_3.json} | 112 +- ...sDistributor_LiquidStakedBNB_3_Proxy.json} | 110 +- deployments/bsctestnet/ComptrollerImpl.json | 2 +- .../RewardsDistributor_LiquidStakedBNB_3.json | 1278 +++++++++++++++++ ...dsDistributor_LiquidStakedBNB_3_Proxy.json | 285 ++++ helpers/deploymentConfig.ts | 26 +- 6 files changed, 1696 insertions(+), 117 deletions(-) rename deployments/bscmainnet/{RewardsDistributor_Stablecoins_2.json => RewardsDistributor_LiquidStakedBNB_3.json} (95%) rename deployments/bscmainnet/{RewardsDistributor_Stablecoins_2_Proxy.json => RewardsDistributor_LiquidStakedBNB_3_Proxy.json} (94%) create mode 100644 deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3.json create mode 100644 deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3.json similarity index 95% rename from deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json rename to deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3.json index 4c20676c1..584510fa0 100644 --- a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2.json +++ b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3.json @@ -1,5 +1,5 @@ { - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", "abi": [ { "anonymous": false, @@ -1129,94 +1129,102 @@ "type": "constructor" } ], - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "receipt": { "to": null, "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", - "contractAddress": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "transactionIndex": 44, + "contractAddress": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "transactionIndex": 19, "gasUsed": "861817", - "logsBloom": "0x00000000020000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000800000000000000000000008000000000000000000000000000000002000001040000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000010000000000080000000000084000000000000800000000000000000000010002000000400000000000000800000000000000000000000000020000000000000000001040000000200000400000000000000000020000000000200000000000000000000000000000800000000000000000000000000", - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1", - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000002000001040000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000010000000000080001000000084000000000000800000000000000000000010802000000400000000000000800000000000000000000000000020000000004000000001040000000200000400000000000000000020000000000200000000000000000000000000000800000000000000000000000000", + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659", + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "logs": [ { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", "topics": [ "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", "0x00000000000000000000000001251d4ef6bb9f56c8bef7d3a201f00f4c122589" ], "data": "0x", - "logIndex": 140, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 33, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000008bda9f9e1fef0dfd404fef338d9fe4c543d172e1" ], "data": "0x", - "logIndex": 141, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 34, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", - "logIndex": 142, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 35, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", - "logIndex": 143, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 36, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 144, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 37, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", - "logIndex": 145, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 38, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" } ], - "blockNumber": 31163500, - "cumulativeGasUsed": "6625169", + "blockNumber": 31166602, + "cumulativeGasUsed": "2237830", "status": 1, "byzantium": true }, "args": [ "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", - "0xbe20309400000000000000000000000094c1495cd4c557f1560cbd68eab0d197e62915710000000000000000000000003bc5ac0dfdc871b365d159f728dd1b9a0b5481e800000000000000000000000000000000000000000000000000000000000000640000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" + "0xbe203094000000000000000000000000d933909a4a2b7a4638903028f44d1d38ce27c3520000000000000000000000003bc5ac0dfdc871b365d159f728dd1b9a0b5481e800000000000000000000000000000000000000000000000000000000000000640000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" ], "numDeployments": 1, "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", @@ -1226,7 +1234,7 @@ "execute": { "methodName": "initialize", "args": [ - "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571", + "0xd933909A4a2b7A4638903028f44D1d38ce27c352", "0x3BC5AC0dFdC871B365d159f728dd1B9A0B5481E8", 100, "0x4788629ABc6cFCA10F9f969efdEAa1cF70c23555" @@ -1267,4 +1275,4 @@ "storage": [], "types": null } -} +} \ No newline at end of file diff --git a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json similarity index 94% rename from deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json rename to deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json index a07501702..f1a6cbd56 100644 --- a/deployments/bscmainnet/RewardsDistributor_Stablecoins_2_Proxy.json +++ b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json @@ -1,5 +1,5 @@ { - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", "abi": [ { "inputs": [ @@ -146,94 +146,102 @@ "type": "receive" } ], - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "receipt": { "to": null, "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", - "contractAddress": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "transactionIndex": 44, + "contractAddress": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "transactionIndex": 19, "gasUsed": "861817", - "logsBloom": "0x00000000020000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000800000000000000000000008000000000000000000000000000000002000001040000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000010000000000080000000000084000000000000800000000000000000000010002000000400000000000000800000000000000000000000000020000000000000000001040000000200000400000000000000000020000000000200000000000000000000000000000800000000000000000000000000", - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1", - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000002000001040000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000010000000000080001000000084000000000000800000000000000000000010802000000400000000000000800000000000000000000000000020000000004000000001040000000200000400000000000000000020000000000200000000000000000000000000000800000000000000000000000000", + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659", + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "logs": [ { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", "topics": [ "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", "0x00000000000000000000000001251d4ef6bb9f56c8bef7d3a201f00f4c122589" ], "data": "0x", - "logIndex": 140, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 33, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000008bda9f9e1fef0dfd404fef338d9fe4c543d172e1" ], "data": "0x", - "logIndex": 141, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 34, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", - "logIndex": 142, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 35, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", - "logIndex": 143, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 36, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 144, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 37, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" }, { - "transactionIndex": 44, - "blockNumber": 31163500, - "transactionHash": "0x38a2e478daf809cc162c5a00b0dd12a3417790aebe43e53c913e45abe8380127", - "address": "0x9E5BFB2cd19499B6dF19C38f9cCa4abAc8568832", - "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "transactionIndex": 19, + "blockNumber": 31166602, + "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", - "logIndex": 145, - "blockHash": "0x12e3888b2eb8c762a5d27471addc99613fc50c19908fe39f59f0a275612af8c1" + "logIndex": 38, + "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" } ], - "blockNumber": 31163500, - "cumulativeGasUsed": "6625169", + "blockNumber": 31166602, + "cumulativeGasUsed": "2237830", "status": 1, "byzantium": true }, "args": [ "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", - "0xbe20309400000000000000000000000094c1495cd4c557f1560cbd68eab0d197e62915710000000000000000000000003bc5ac0dfdc871b365d159f728dd1b9a0b5481e800000000000000000000000000000000000000000000000000000000000000640000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" + "0xbe203094000000000000000000000000d933909a4a2b7a4638903028f44d1d38ce27c3520000000000000000000000003bc5ac0dfdc871b365d159f728dd1b9a0b5481e800000000000000000000000000000000000000000000000000000000000000640000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" ], "numDeployments": 1, "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", @@ -274,4 +282,4 @@ "storage": [], "types": null } -} +} \ No newline at end of file diff --git a/deployments/bsctestnet/ComptrollerImpl.json b/deployments/bsctestnet/ComptrollerImpl.json index 3573ebe1f..c460085f2 100644 --- a/deployments/bsctestnet/ComptrollerImpl.json +++ b/deployments/bsctestnet/ComptrollerImpl.json @@ -1,5 +1,5 @@ { - "address": "0x80691DaD6dAb8a028FFE68bb8045f2547d210f9D", + "address": "0x069705246364d60c5503bF19b4A714ab412521a0", "abi": [ { "inputs": [ diff --git a/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3.json new file mode 100644 index 000000000..dd3411f4f --- /dev/null +++ b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3.json @@ -0,0 +1,1278 @@ +{ + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "receipt": { + "to": null, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "transactionIndex": 1, + "gasUsed": "865817", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000080000000000000000000000000000000000000000000000000000000008000000000000000000000100000000002000001040000000000000000000000000000000000020000000000000000000801000000800000000000000000000000400000000000000000000000000000000080000000000080000000000000800000000000000000000012002000000400000000000000800000000000000000000000000020000000000000000001040000000000000400000000000000000020000000000200000000000000000000000000000800000000000000000000800001", + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028", + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000fae44cf6309598c2557bb265bf0401d594db97da" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008bda9f9e1fef0dfd404fef338d9fe4c543d172e1" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", + "logIndex": 2, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 3, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 4, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", + "logIndex": 5, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + } + ], + "blockNumber": 32762473, + "cumulativeGasUsed": "886817", + "status": 1, + "byzantium": true + }, + "args": [ + "0xfAE44cf6309598c2557Bb265BF0401D594db97DA", + "0xef480a5654b231ff7d80A0681F938f3Db71a6Ca6", + "0xbe203094000000000000000000000000596b11acaacf03217287939f88d63b51d3771704000000000000000000000000ac7d6b77ebd1db8c5a9f0896e5eb5d485cb677b3000000000000000000000000000000000000000000000000000000000000006400000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0x596B11acAACF03217287939f88d63b51d3771704", + "0xac7D6B77EBD1DB8C5a9f0896e5eB5d485CB677b3", + 100, + "0x45f8a08F534f34A97187626E05d4b6648Eeaa9AA" + ] + }, + "implementation": "0xfAE44cf6309598c2557Bb265BF0401D594db97DA", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json new file mode 100644 index 000000000..f4c46ea59 --- /dev/null +++ b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json @@ -0,0 +1,285 @@ +{ + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "receipt": { + "to": null, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "transactionIndex": 1, + "gasUsed": "865817", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000080000000000000000000000000000000000000000000000000000000008000000000000000000000100000000002000001040000000000000000000000000000000000020000000000000000000801000000800000000000000000000000400000000000000000000000000000000080000000000080000000000000800000000000000000000012002000000400000000000000800000000000000000000000000020000000000000000001040000000000000400000000000000000020000000000200000000000000000000000000000800000000000000000000800001", + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028", + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000fae44cf6309598c2557bb265bf0401d594db97da" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008bda9f9e1fef0dfd404fef338d9fe4c543d172e1" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", + "logIndex": 2, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 3, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 4, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + }, + { + "transactionIndex": 1, + "blockNumber": 32762473, + "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", + "logIndex": 5, + "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" + } + ], + "blockNumber": 32762473, + "cumulativeGasUsed": "886817", + "status": 1, + "byzantium": true + }, + "args": [ + "0xfAE44cf6309598c2557Bb265BF0401D594db97DA", + "0xef480a5654b231ff7d80A0681F938f3Db71a6Ca6", + "0xbe203094000000000000000000000000596b11acaacf03217287939f88d63b51d3771704000000000000000000000000ac7d6b77ebd1db8c5a9f0896e5eb5d485cb677b3000000000000000000000000000000000000000000000000000000000000006400000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index d5f4828ab..ddf3e0c99 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -725,12 +725,6 @@ export const globalConfig: NetworkConfig = { supplySpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) borrowSpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) }, - { - asset: "SD", - markets: ["SD"], - supplySpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) - borrowSpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) - }, ], }, { @@ -1078,6 +1072,12 @@ export const globalConfig: NetworkConfig = { supplySpeeds: ["3703703703703703"], // 3200 SD over 30 days (864000 blocks) borrowSpeeds: ["3703703703703703"], // 3200 SD over 30 days (864000 blocks) }, + { + asset: "SD", + markets: ["BNBx"], + supplySpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + borrowSpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + }, ], }, { @@ -1427,13 +1427,7 @@ export const globalConfig: NetworkConfig = { markets: ["HAY"], supplySpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) borrowSpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) - }, - { - asset: "SD", - markets: ["SD"], - supplySpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) - borrowSpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) - }, + } ], }, { @@ -1783,6 +1777,12 @@ export const globalConfig: NetworkConfig = { supplySpeeds: ["3703703703703703"], // 3200 SD over 30 days (864000 blocks) borrowSpeeds: ["3703703703703703"], // 3200 SD over 30 days (864000 blocks) }, + { + asset: "SD", + markets: ["BNBx"], + supplySpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + borrowSpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + }, ], }, { From 5c62416d2fa791be949c7d37b0490ca221a87e9d Mon Sep 17 00:00:00 2001 From: Narayan Prusty Date: Fri, 25 Aug 2023 18:47:34 +0100 Subject: [PATCH 18/39] fix: redeployed HAY reward distributors --- .../RewardsDistributor_StableCoins_1.json | 112 ++++++++++-------- ...ewardsDistributor_StableCoins_1_Proxy.json | 112 ++++++++++-------- 2 files changed, 120 insertions(+), 104 deletions(-) diff --git a/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json b/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json index b083be577..fd585a9c8 100644 --- a/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json +++ b/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json @@ -1,5 +1,5 @@ { - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "abi": [ { "anonymous": false, @@ -1129,87 +1129,95 @@ "type": "constructor" } ], - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "receipt": { "to": null, - "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", - "contractAddress": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "transactionIndex": 0, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "transactionIndex": 1, "gasUsed": "865817", - "logsBloom": "0x1000000000000000000000000000000040000000000000000080000800000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000002000001000000000000000000000000001000000000020000000000000000000800000000800000000000000000000000400000000040000000000000000000000000000000000080000000000000800000010000000000000002002000000400000000000000800000000000000000000000000020000000000000000001040000000000000400000000000000000020000000000200000000000000000000000000000800000000000000000000800001", - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2", - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "logsBloom": "0x00000000000000000000000080000000400000000000000000800000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000002000001040000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000000000000000080000000000080000000000000800000000000000000000012002000040400000000000000800000000000000000000000000020000000000000000001040000000000000400000000000000000020000000000200000000000000000020000000000800000000000000000000800001", + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870", + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "logs": [ { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "topics": [ "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", "0x000000000000000000000000fae44cf6309598c2557bb265bf0401d594db97da" ], "data": "0x", - "logIndex": 0, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 10, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + "0x0000000000000000000000008bda9f9e1fef0dfd404fef338d9fe4c543d172e1" ], "data": "0x", - "logIndex": 1, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 11, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", - "logIndex": 2, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 12, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", - "logIndex": 3, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 13, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 4, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 14, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", - "logIndex": 5, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 15, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" } ], - "blockNumber": 32321303, - "cumulativeGasUsed": "865817", + "blockNumber": 32762816, + "cumulativeGasUsed": "1100153", "status": 1, "byzantium": true }, @@ -1267,4 +1275,4 @@ "storage": [], "types": null } -} +} \ No newline at end of file diff --git a/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json b/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json index ef3c25a64..e4cc904e0 100644 --- a/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json +++ b/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json @@ -1,5 +1,5 @@ { - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "abi": [ { "inputs": [ @@ -146,87 +146,95 @@ "type": "receive" } ], - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "receipt": { "to": null, - "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", - "contractAddress": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "transactionIndex": 0, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "transactionIndex": 1, "gasUsed": "865817", - "logsBloom": "0x1000000000000000000000000000000040000000000000000080000800000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000002000001000000000000000000000000001000000000020000000000000000000800000000800000000000000000000000400000000040000000000000000000000000000000000080000000000000800000010000000000000002002000000400000000000000800000000000000000000000000020000000000000000001040000000000000400000000000000000020000000000200000000000000000000000000000800000000000000000000800001", - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2", - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", + "logsBloom": "0x00000000000000000000000080000000400000000000000000800000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000002000001040000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000000000000000080000000000080000000000000800000000000000000000012002000040400000000000000800000000000000000000000000020000000000000000001040000000000000400000000000000000020000000000200000000000000000020000000000800000000000000000000800001", + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870", + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "logs": [ { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "topics": [ "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", "0x000000000000000000000000fae44cf6309598c2557bb265bf0401d594db97da" ], "data": "0x", - "logIndex": 0, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 10, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + "0x0000000000000000000000008bda9f9e1fef0dfd404fef338d9fe4c543d172e1" ], "data": "0x", - "logIndex": 1, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 11, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "topics": [ + "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" + ], "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", - "logIndex": 2, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 12, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "topics": [ + "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" + ], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", - "logIndex": 3, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 13, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 4, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 14, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" }, { - "transactionIndex": 0, - "blockNumber": 32321303, - "transactionHash": "0xc8bc7138422f13c46ca59ed5ad367f76dd209d71b4c501f6e65567d8c3002013", - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", - "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "transactionIndex": 1, + "blockNumber": 32762816, + "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", - "logIndex": 5, - "blockHash": "0xa651cd3f33db6becfc6d28f2ef34162078707cc0a36092dcf6fc1629787332e2" + "logIndex": 15, + "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" } ], - "blockNumber": 32321303, - "cumulativeGasUsed": "865817", + "blockNumber": 32762816, + "cumulativeGasUsed": "1100153", "status": 1, "byzantium": true }, @@ -274,4 +282,4 @@ "storage": [], "types": null } -} +} \ No newline at end of file From eab087d8ee7b38c525b3cccaa148686f5713ecdd Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Tue, 29 Aug 2023 10:24:38 +0200 Subject: [PATCH 19/39] style: fix a comment and linter --- .../RewardsDistributor_LiquidStakedBNB_3.json | 18 +++++------------- ...rdsDistributor_LiquidStakedBNB_3_Proxy.json | 18 +++++------------- .../RewardsDistributor_LiquidStakedBNB_3.json | 18 +++++------------- ...rdsDistributor_LiquidStakedBNB_3_Proxy.json | 18 +++++------------- .../RewardsDistributor_StableCoins_1.json | 18 +++++------------- ...RewardsDistributor_StableCoins_1_Proxy.json | 18 +++++------------- helpers/deploymentConfig.ts | 10 +++++----- 7 files changed, 35 insertions(+), 83 deletions(-) diff --git a/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3.json index 584510fa0..0b21fda5e 100644 --- a/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3.json +++ b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3.json @@ -1172,9 +1172,7 @@ "blockNumber": 31166602, "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", "logIndex": 35, "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" @@ -1184,9 +1182,7 @@ "blockNumber": 31166602, "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 36, "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" @@ -1196,9 +1192,7 @@ "blockNumber": 31166602, "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 37, "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" @@ -1208,9 +1202,7 @@ "blockNumber": 31166602, "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", "logIndex": 38, "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" @@ -1275,4 +1267,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json index f1a6cbd56..2788f2efa 100644 --- a/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json +++ b/deployments/bscmainnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json @@ -189,9 +189,7 @@ "blockNumber": 31166602, "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", "logIndex": 35, "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" @@ -201,9 +199,7 @@ "blockNumber": 31166602, "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 36, "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" @@ -213,9 +209,7 @@ "blockNumber": 31166602, "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 37, "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" @@ -225,9 +219,7 @@ "blockNumber": 31166602, "transactionHash": "0x0266c33732d21aa321c25dd1d7a3db6b65f5eb615006106569413d8e6f64bc52", "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", "logIndex": 38, "blockHash": "0x4ed552ca25c452b2778daaca4861ddaa380c19700c089d7a6a9fd6782c160659" @@ -282,4 +274,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3.json index dd3411f4f..3b24ffa8c 100644 --- a/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3.json +++ b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3.json @@ -1172,9 +1172,7 @@ "blockNumber": 32762473, "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", "logIndex": 2, "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" @@ -1184,9 +1182,7 @@ "blockNumber": 32762473, "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 3, "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" @@ -1196,9 +1192,7 @@ "blockNumber": 32762473, "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 4, "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" @@ -1208,9 +1202,7 @@ "blockNumber": 32762473, "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", "logIndex": 5, "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" @@ -1275,4 +1267,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json index f4c46ea59..785bc5f80 100644 --- a/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json +++ b/deployments/bsctestnet/RewardsDistributor_LiquidStakedBNB_3_Proxy.json @@ -189,9 +189,7 @@ "blockNumber": 32762473, "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", "logIndex": 2, "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" @@ -201,9 +199,7 @@ "blockNumber": 32762473, "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 3, "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" @@ -213,9 +209,7 @@ "blockNumber": 32762473, "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 4, "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" @@ -225,9 +219,7 @@ "blockNumber": 32762473, "transactionHash": "0x5768bb017cc9fec2297e2439a767a48a5f1077ca81a4d36dac888dec99de6306", "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", "logIndex": 5, "blockHash": "0x1613923b976b1ffb0227130b96a04f0253670ee0d610b17249cb5c648fe9f028" @@ -282,4 +274,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json b/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json index fd585a9c8..642db0396 100644 --- a/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json +++ b/deployments/bsctestnet/RewardsDistributor_StableCoins_1.json @@ -1172,9 +1172,7 @@ "blockNumber": 32762816, "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", "logIndex": 12, "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" @@ -1184,9 +1182,7 @@ "blockNumber": 32762816, "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 13, "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" @@ -1196,9 +1192,7 @@ "blockNumber": 32762816, "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 14, "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" @@ -1208,9 +1202,7 @@ "blockNumber": 32762816, "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", "logIndex": 15, "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" @@ -1275,4 +1267,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json b/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json index e4cc904e0..62628f572 100644 --- a/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json +++ b/deployments/bsctestnet/RewardsDistributor_StableCoins_1_Proxy.json @@ -189,9 +189,7 @@ "blockNumber": 32762816, "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", - "topics": [ - "0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0" - ], + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", "logIndex": 12, "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" @@ -201,9 +199,7 @@ "blockNumber": 32762816, "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", - "topics": [ - "0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa" - ], + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", "logIndex": 13, "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" @@ -213,9 +209,7 @@ "blockNumber": 32762816, "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 14, "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" @@ -225,9 +219,7 @@ "blockNumber": 32762816, "transactionHash": "0xe64fbf405280c3d4a45bbe5e29f1f9105c7fed31ecc35d3700ac374d03bc6f23", "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef480a5654b231ff7d80a0681f938f3db71a6ca6", "logIndex": 15, "blockHash": "0x014cb4c0ae154549cd2f720956437c3448cd0445bbf0a62383e8b9f0d4262870" @@ -282,4 +274,4 @@ "storage": [], "types": null } -} \ No newline at end of file +} diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index ddf3e0c99..b762dca5c 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -1075,8 +1075,8 @@ export const globalConfig: NetworkConfig = { { asset: "SD", markets: ["BNBx"], - supplySpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) - borrowSpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + supplySpeeds: ["1157407407407407"], // 1000 SD over 30 days (864000 blocks) + borrowSpeeds: ["1157407407407407"], // 1000 SD over 30 days (864000 blocks) }, ], }, @@ -1427,7 +1427,7 @@ export const globalConfig: NetworkConfig = { markets: ["HAY"], supplySpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) borrowSpeeds: ["1240079365079365"], // 1000 HAY over 28 days (806400 blocks) - } + }, ], }, { @@ -1780,8 +1780,8 @@ export const globalConfig: NetworkConfig = { { asset: "SD", markets: ["BNBx"], - supplySpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) - borrowSpeeds: ["1157407407407407"], // 1000 SD over 28 days (806400 blocks) + supplySpeeds: ["1157407407407407"], // 1000 SD over 30 days (864000 blocks) + borrowSpeeds: ["1157407407407407"], // 1000 SD over 30 days (864000 blocks) }, ], }, From 09554032ca5ed3b04db228d5359a2e4db2fa8fd3 Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Tue, 29 Aug 2023 13:22:24 +0200 Subject: [PATCH 20/39] fix: set the last reward distributor deployed for HAY --- deployments/bsctestnet.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployments/bsctestnet.json b/deployments/bsctestnet.json index faa4bf47d..b41b3c6a4 100644 --- a/deployments/bsctestnet.json +++ b/deployments/bsctestnet.json @@ -22875,7 +22875,7 @@ ] }, "RewardsDistributor_StableCoins_1": { - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "abi": [ { "anonymous": false, @@ -24007,7 +24007,7 @@ ] }, "RewardsDistributor_StableCoins_1_Proxy": { - "address": "0xFFfC3fC29AFdc14408F1461d9AD4Ba976E25dcDc", + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "abi": [ { "inputs": [ From 5e8a08218984caed92fb6591f03c53648478f8ea Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Tue, 29 Aug 2023 13:54:22 +0200 Subject: [PATCH 21/39] feat: add deployment info for the last rewards in the LSB pool --- deployments/bscmainnet.json | 1281 +++++++++++++++++++++++++++++++++++ 1 file changed, 1281 insertions(+) diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index 1e089a136..36fbc5c45 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -16505,6 +16505,1287 @@ } ] }, + "RewardsDistributor_LiquidStakedBNB_3": { + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RewardsDistributor_LiquidStakedBNB_3_Proxy": { + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, "RewardsDistributor_Stablecoins_0": { "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", "abi": [ From ec1d8b32e120a0cc52acca8c8ca5bb922d805ac8 Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Tue, 29 Aug 2023 14:58:19 +0200 Subject: [PATCH 22/39] docs: add audit on Comptroller and several RewardsDistributor --- audits/069_comptroller_certik_20230824.pdf | Bin 0 -> 1180644 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 audits/069_comptroller_certik_20230824.pdf diff --git a/audits/069_comptroller_certik_20230824.pdf b/audits/069_comptroller_certik_20230824.pdf new file mode 100644 index 0000000000000000000000000000000000000000..56a64f93de97e34113b0c59c903bab863bfd92d1 GIT binary patch literal 1180644 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

wUyY=E3~M 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 W&HCv~Dcp6kouJMeznb#hC6QjKvQ9s1p%v={ufg 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

luH;UdmGj@HZ@FcW?0=9{^g5I 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%0A?k+!vN#=tF^UC02Cn7$UsEh4 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≧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

0=9Jt&J|sx#Ngb6T*0{?dupp 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 J6`3Bo;mAv?LubyFve55GCdDG~* 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 K2o2D?|F*!SRkS+|?eZF+l9GjpI` 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 l++yKePtBkIB#KyGU{{Xoxk(~el literal 0 HcmV?d00001 From 7a6384d3113d01f8291da6f9c086a79487b3ea6a Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Thu, 31 Aug 2023 11:08:37 +0000 Subject: [PATCH 23/39] chore(release): 2.0.0-dev.8 [skip ci] ## [2.0.0-dev.8](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.7...v2.0.0-dev.8) (2023-08-31) ### Features * add deployment info for the last rewards in the LSB pool ([5e8a082](https://github.com/VenusProtocol/isolated-pools/commit/5e8a08218984caed92fb6591f03c53648478f8ea)) * deploy HAY rewards distributor ([30325ea](https://github.com/VenusProtocol/isolated-pools/commit/30325ea4a680f2b81457ce7f72f857292ccf18bf)) * deployed SD Rewards distributor ([98b514d](https://github.com/VenusProtocol/isolated-pools/commit/98b514dc49b38c3a37eaf9a8d69081ffdd7d7516)) ### Bug Fixes * added SD rewards distributor ([ed4ed8a](https://github.com/VenusProtocol/isolated-pools/commit/ed4ed8a3a26620d06143cf9912889cb82bb35cd9)) * deployed latest comptroller ([3599ed4](https://github.com/VenusProtocol/isolated-pools/commit/3599ed40c6c10f1f09df2d7288566eccb7c6e2a2)) * deployed reward distributors for mainnet and testnet ([2aedd92](https://github.com/VenusProtocol/isolated-pools/commit/2aedd92714a101d2ce8d255ab24051049d647ed3)) * fix deployment of comptroller and verification ([50d6edd](https://github.com/VenusProtocol/isolated-pools/commit/50d6edd8e6184407777eeb8fc281fe3862a7988c)) * redeployed HAY reward distributors ([5c62416](https://github.com/VenusProtocol/isolated-pools/commit/5c62416d2fa791be949c7d37b0490ca221a87e9d)) * set the last reward distributor deployed for HAY ([0955403](https://github.com/VenusProtocol/isolated-pools/commit/09554032ca5ed3b04db228d5359a2e4db2fa8fd3)) --- CHANGELOG.md | 19 +++++++++++++++++++ package.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66114bbcf..f224081ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## [2.0.0-dev.8](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.7...v2.0.0-dev.8) (2023-08-31) + + +### Features + +* add deployment info for the last rewards in the LSB pool ([5e8a082](https://github.com/VenusProtocol/isolated-pools/commit/5e8a08218984caed92fb6591f03c53648478f8ea)) +* deploy HAY rewards distributor ([30325ea](https://github.com/VenusProtocol/isolated-pools/commit/30325ea4a680f2b81457ce7f72f857292ccf18bf)) +* deployed SD Rewards distributor ([98b514d](https://github.com/VenusProtocol/isolated-pools/commit/98b514dc49b38c3a37eaf9a8d69081ffdd7d7516)) + + +### Bug Fixes + +* added SD rewards distributor ([ed4ed8a](https://github.com/VenusProtocol/isolated-pools/commit/ed4ed8a3a26620d06143cf9912889cb82bb35cd9)) +* deployed latest comptroller ([3599ed4](https://github.com/VenusProtocol/isolated-pools/commit/3599ed40c6c10f1f09df2d7288566eccb7c6e2a2)) +* deployed reward distributors for mainnet and testnet ([2aedd92](https://github.com/VenusProtocol/isolated-pools/commit/2aedd92714a101d2ce8d255ab24051049d647ed3)) +* fix deployment of comptroller and verification ([50d6edd](https://github.com/VenusProtocol/isolated-pools/commit/50d6edd8e6184407777eeb8fc281fe3862a7988c)) +* redeployed HAY reward distributors ([5c62416](https://github.com/VenusProtocol/isolated-pools/commit/5c62416d2fa791be949c7d37b0490ca221a87e9d)) +* set the last reward distributor deployed for HAY ([0955403](https://github.com/VenusProtocol/isolated-pools/commit/09554032ca5ed3b04db228d5359a2e4db2fa8fd3)) + ## [2.0.0-dev.7](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.6...v2.0.0-dev.7) (2023-08-24) ## [2.0.0-dev.6](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.5...v2.0.0-dev.6) (2023-08-24) diff --git a/package.json b/package.json index f3af08f4a..8b5fe864c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "2.0.0-dev.7", + "version": "2.0.0-dev.8", "description": "", "files": [ "artifacts", From 3b5665772569fd82667d68a5607500b6fe13051c Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Fri, 1 Sep 2023 15:42:41 +0000 Subject: [PATCH 24/39] chore(release): 2.0.0-dev.9 [skip ci] ## [2.0.0-dev.9](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.8...v2.0.0-dev.9) (2023-09-01) ### Features * make convertibleBaseAsset configurable ([d8d49de](https://github.com/VenusProtocol/isolated-pools/commit/d8d49de42c718fdeceb6bf31da5dc9265ccaf191)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f224081ec..24f240080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [2.0.0-dev.9](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.8...v2.0.0-dev.9) (2023-09-01) + + +### Features + +* make convertibleBaseAsset configurable ([d8d49de](https://github.com/VenusProtocol/isolated-pools/commit/d8d49de42c718fdeceb6bf31da5dc9265ccaf191)) + ## [2.0.0-dev.8](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.7...v2.0.0-dev.8) (2023-08-31) diff --git a/package.json b/package.json index 8b5fe864c..d3ed836a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "2.0.0-dev.8", + "version": "2.0.0-dev.9", "description": "", "files": [ "artifacts", From 1b5c8a7e269924cd3f0c7a0fd0a89c6344d51e98 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Wed, 6 Sep 2023 08:44:16 +0530 Subject: [PATCH 25/39] chore: update solidity prettier package version --- contracts/Comptroller.sol | 99 +++----------- contracts/ComptrollerInterface.sol | 25 +--- contracts/ExponentialNoError.sol | 6 +- contracts/Lens/PoolLens.sol | 50 +++---- contracts/Pool/PoolRegistry.sol | 6 +- contracts/Rewards/RewardsDistributor.sol | 12 +- contracts/RiskFund/ProtocolShareReserve.sol | 14 +- contracts/RiskFund/RiskFund.sol | 10 +- contracts/Shortfall/Shortfall.sol | 6 +- contracts/VToken.sol | 63 ++------- contracts/VTokenInterfaces.sol | 29 +--- contracts/lib/ApproveOrRevert.sol | 6 +- contracts/lib/TokenDebtTracker.sol | 18 +-- contracts/test/ERC20.sol | 44 +----- contracts/test/EvilToken.sol | 6 +- contracts/test/FaucetToken.sol | 12 +- contracts/test/FeeToken.sol | 6 +- contracts/test/MockDeflationaryToken.sol | 18 +-- contracts/test/Mocks/MockPancakeSwap.sol | 128 ++++-------------- contracts/test/Mocks/MockToken.sol | 6 +- contracts/test/SafeMath.sol | 30 +--- contracts/test/VTokenHarness.sol | 24 +--- contracts/test/lib/ApproveOrRevertHarness.sol | 6 +- .../test/lib/TokenDebtTrackerHarness.sol | 12 +- package.json | 2 +- .../contracts/CErc20DelegateCertora.sol | 6 +- .../contracts/CErc20DelegatorCertora.sol | 6 +- .../contracts/CErc20ImmutableCertora.sol | 6 +- spec/certora/contracts/ComptrollerCertora.sol | 11 +- spec/certora/contracts/TimelockCertora.sol | 18 +-- .../contracts/UnderlyingModelNonStandard.sol | 6 +- .../contracts/UnderlyingModelWithFee.sol | 6 +- spec/certora/contracts/mcd/Dai.sol | 12 +- spec/certora/contracts/mcd/Pot.sol | 22 +-- spec/certora/contracts/mcd/Vat.sol | 65 ++------- spec/certora/contracts/mcd/join.sol | 30 +--- yarn.lock | 23 ++-- 37 files changed, 177 insertions(+), 672 deletions(-) diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index 9d2de5830..eb473cded 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -269,11 +269,7 @@ contract Comptroller is * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting * @custom:access Not restricted */ - function preMintHook( - address vToken, - address minter, - uint256 mintAmount - ) external override { + function preMintHook(address vToken, address minter, uint256 mintAmount) external override { _checkActionPauseState(vToken, Action.MINT); if (!markets[vToken].isListed) { @@ -313,11 +309,7 @@ contract Comptroller is * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset * @custom:access Not restricted */ - function preRedeemHook( - address vToken, - address redeemer, - uint256 redeemTokens - ) external override { + function preRedeemHook(address vToken, address redeemer, uint256 redeemTokens) external override { _checkActionPauseState(vToken, Action.REDEEM); _checkRedeemAllowed(vToken, redeemer, redeemTokens); @@ -346,11 +338,7 @@ contract Comptroller is * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken */ /// disable-eslint - function preBorrowHook( - address vToken, - address borrower, - uint256 borrowAmount - ) external override { + function preBorrowHook(address vToken, address borrower, uint256 borrowAmount) external override { _checkActionPauseState(vToken, Action.BORROW); if (!markets[vToken].isListed) { @@ -574,12 +562,7 @@ contract Comptroller is * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset * @custom:access Not restricted */ - function preTransferHook( - address vToken, - address src, - address dst, - uint256 transferTokens - ) external override { + function preTransferHook(address vToken, address src, address dst, uint256 transferTokens) external override { _checkActionPauseState(vToken, Action.TRANSFER); // Currently the only consideration is whether or not @@ -920,11 +903,7 @@ contract Comptroller is * @param paused The new paused state (true=paused, false=unpaused) * @custom:access Controlled by AccessControlManager */ - function setActionsPaused( - VToken[] calldata marketsList, - Action[] calldata actionsList, - bool paused - ) external { + function setActionsPaused(VToken[] calldata marketsList, Action[] calldata actionsList, bool paused) external { _checkAccessAllowed("setActionsPaused(address[],uint256[],bool)"); uint256 marketsCount = marketsList.length; @@ -1012,15 +991,9 @@ contract Comptroller is * @return liquidity Account liquidity in excess of liquidation threshold requirements, * @return shortfall Account shortfall below liquidation threshold requirements */ - function getAccountLiquidity(address account) - external - view - returns ( - uint256 error, - uint256 liquidity, - uint256 shortfall - ) - { + function getAccountLiquidity( + address account + ) external view returns (uint256 error, uint256 liquidity, uint256 shortfall) { AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold); return (NO_ERROR, snapshot.liquidity, snapshot.shortfall); } @@ -1033,15 +1006,9 @@ contract Comptroller is * @return liquidity Account liquidity in excess of collateral requirements, * @return shortfall Account shortfall below collateral requirements */ - function getBorrowingPower(address account) - external - view - returns ( - uint256 error, - uint256 liquidity, - uint256 shortfall - ) - { + function getBorrowingPower( + address account + ) external view returns (uint256 error, uint256 liquidity, uint256 shortfall) { AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor); return (NO_ERROR, snapshot.liquidity, snapshot.shortfall); } @@ -1062,15 +1029,7 @@ contract Comptroller is address vTokenModify, uint256 redeemTokens, uint256 borrowAmount - ) - external - view - returns ( - uint256 error, - uint256 liquidity, - uint256 shortfall - ) - { + ) external view returns (uint256 error, uint256 liquidity, uint256 shortfall) { AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot( account, VToken(vTokenModify), @@ -1289,11 +1248,7 @@ contract Comptroller is * @param action Action id to pause/unpause * @param paused The new paused state (true=paused, false=unpaused) */ - function _setActionPaused( - address market, - Action action, - bool paused - ) internal { + function _setActionPaused(address market, Action action, bool paused) internal { require(markets[market].isListed, "cannot pause a market that is not listed"); _actionPaused[market][action] = paused; emit ActionPausedMarket(VToken(market), action, paused); @@ -1305,11 +1260,7 @@ contract Comptroller is * @param redeemer Account redeeming the tokens * @param redeemTokens The number of tokens to redeem */ - function _checkRedeemAllowed( - address vToken, - address redeemer, - uint256 redeemTokens - ) internal { + function _checkRedeemAllowed(address vToken, address redeemer, uint256 redeemTokens) internal { Market storage market = markets[vToken]; if (!market.isListed) { @@ -1346,11 +1297,10 @@ contract Comptroller is * without calculating accumulated interest. * @return snapshot Account liquidity snapshot */ - function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight) - internal - view - returns (AccountLiquiditySnapshot memory snapshot) - { + function _getCurrentLiquiditySnapshot( + address account, + function(VToken) internal view returns (Exp memory) weight + ) internal view returns (AccountLiquiditySnapshot memory snapshot) { return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight); } @@ -1472,15 +1422,10 @@ contract Comptroller is * @return borrowBalance Borrowed amount, including the interest * @return exchangeRateMantissa Stored exchange rate */ - function _safeGetAccountSnapshot(VToken vToken, address user) - internal - view - returns ( - uint256 vTokenBalance, - uint256 borrowBalance, - uint256 exchangeRateMantissa - ) - { + function _safeGetAccountSnapshot( + VToken vToken, + address user + ) internal view returns (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) { uint256 err; (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user); if (err != 0) { diff --git a/contracts/ComptrollerInterface.sol b/contracts/ComptrollerInterface.sol index ce00ae3c5..d1879f90a 100644 --- a/contracts/ComptrollerInterface.sol +++ b/contracts/ComptrollerInterface.sol @@ -20,23 +20,11 @@ interface ComptrollerInterface { /*** Policy Hooks ***/ - function preMintHook( - address vToken, - address minter, - uint256 mintAmount - ) external; + function preMintHook(address vToken, address minter, uint256 mintAmount) external; - function preRedeemHook( - address vToken, - address redeemer, - uint256 redeemTokens - ) external; + function preRedeemHook(address vToken, address redeemer, uint256 redeemTokens) external; - function preBorrowHook( - address vToken, - address borrower, - uint256 borrowAmount - ) external; + function preBorrowHook(address vToken, address borrower, uint256 borrowAmount) external; function preRepayHook(address vToken, address borrower) external; @@ -55,12 +43,7 @@ interface ComptrollerInterface { address borrower ) external; - function preTransferHook( - address vToken, - address src, - address dst, - uint256 transferTokens - ) external; + function preTransferHook(address vToken, address src, address dst, uint256 transferTokens) external; function isComptroller() external view returns (bool); diff --git a/contracts/ExponentialNoError.sol b/contracts/ExponentialNoError.sol index a4c5e6b9d..ed39c6a48 100644 --- a/contracts/ExponentialNoError.sol +++ b/contracts/ExponentialNoError.sol @@ -46,11 +46,7 @@ contract ExponentialNoError { * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer. */ // solhint-disable-next-line func-name-mixedcase - function mul_ScalarTruncateAddUInt( - Exp memory a, - uint256 scalar, - uint256 addend - ) internal pure returns (uint256) { + function mul_ScalarTruncateAddUInt(Exp memory a, uint256 scalar, uint256 addend) internal pure returns (uint256) { Exp memory product = mul_(a, scalar); return add_(truncate(product), addend); } diff --git a/contracts/Lens/PoolLens.sol b/contracts/Lens/PoolLens.sol index 54124238f..de29c8b31 100644 --- a/contracts/Lens/PoolLens.sol +++ b/contracts/Lens/PoolLens.sol @@ -177,11 +177,10 @@ contract PoolLens is ExponentialNoError { * @param comptroller The Comptroller implementation address * @return PoolData structure containing the details of the pool */ - function getPoolByComptroller(address poolRegistryAddress, address comptroller) - external - view - returns (PoolData memory) - { + function getPoolByComptroller( + address poolRegistryAddress, + address comptroller + ) external view returns (PoolData memory) { PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress); return getPoolDataFromVenusPool(poolRegistryAddress, poolRegistryInterface.getPoolByComptroller(comptroller)); } @@ -208,11 +207,10 @@ contract PoolLens is ExponentialNoError { * @param asset The underlying asset of vToken * @return A list of Comptroller contracts */ - function getPoolsSupportedByAsset(address poolRegistryAddress, address asset) - external - view - returns (address[] memory) - { + function getPoolsSupportedByAsset( + address poolRegistryAddress, + address asset + ) external view returns (address[] memory) { PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress); return poolRegistryInterface.getPoolsSupportedByAsset(asset); } @@ -222,11 +220,9 @@ contract PoolLens is ExponentialNoError { * @param vTokens The list of vToken addresses * @return An array containing the price data for each asset */ - function vTokenUnderlyingPriceAll(VToken[] calldata vTokens) - external - view - returns (VTokenUnderlyingPrice[] memory) - { + function vTokenUnderlyingPriceAll( + VToken[] calldata vTokens + ) external view returns (VTokenUnderlyingPrice[] memory) { uint256 vTokenCount = vTokens.length; VTokenUnderlyingPrice[] memory res = new VTokenUnderlyingPrice[](vTokenCount); for (uint256 i; i < vTokenCount; ++i) { @@ -241,14 +237,13 @@ contract PoolLens is ExponentialNoError { * @param comptrollerAddress address * @return Pending rewards array */ - function getPendingRewards(address account, address comptrollerAddress) - external - view - returns (RewardSummary[] memory) - { + function getPendingRewards( + address account, + address comptrollerAddress + ) external view returns (RewardSummary[] memory) { VToken[] memory markets = ComptrollerInterface(comptrollerAddress).getAllMarkets(); RewardsDistributor[] memory rewardsDistributors = ComptrollerViewInterface(comptrollerAddress) - .getRewardDistributors(); + .getRewardDistributors(); RewardSummary[] memory rewardSummary = new RewardSummary[](rewardsDistributors.length); for (uint256 i; i < rewardsDistributors.length; ++i) { RewardSummary memory reward; @@ -333,11 +328,10 @@ contract PoolLens is ExponentialNoError { * @param venusPool The VenusPool Object from PoolRegistry * @return Enriched PoolData */ - function getPoolDataFromVenusPool(address poolRegistryAddress, PoolRegistry.VenusPool memory venusPool) - public - view - returns (PoolData memory) - { + function getPoolDataFromVenusPool( + address poolRegistryAddress, + PoolRegistry.VenusPool memory venusPool + ) public view returns (PoolData memory) { // Get tokens in the Pool ComptrollerInterface comptrollerInstance = ComptrollerInterface(venusPool.comptroller); @@ -447,10 +441,10 @@ contract PoolLens is ExponentialNoError { // Market borrow and supply state we will modify update in-memory, in order to not modify storage RewardTokenState memory borrowState; (borrowState.index, borrowState.block, borrowState.lastRewardingBlock) = rewardsDistributor - .rewardTokenBorrowState(address(markets[i])); + .rewardTokenBorrowState(address(markets[i])); RewardTokenState memory supplyState; (supplyState.index, supplyState.block, supplyState.lastRewardingBlock) = rewardsDistributor - .rewardTokenSupplyState(address(markets[i])); + .rewardTokenSupplyState(address(markets[i])); Exp memory marketBorrowIndex = Exp({ mantissa: markets[i].borrowIndex() }); // Update market supply and borrow index in-memory diff --git a/contracts/Pool/PoolRegistry.sol b/contracts/Pool/PoolRegistry.sol index 3b33ade1f..4a5b0e16e 100644 --- a/contracts/Pool/PoolRegistry.sol +++ b/contracts/Pool/PoolRegistry.sol @@ -292,11 +292,7 @@ contract PoolRegistry is Ownable2StepUpgradeable, AccessControlledV8, PoolRegist return numberOfPools_; } - function _transferIn( - IERC20Upgradeable token, - address from, - uint256 amount - ) internal returns (uint256) { + function _transferIn(IERC20Upgradeable token, address from, uint256 amount) internal returns (uint256) { uint256 balanceBefore = token.balanceOf(address(this)); token.safeTransferFrom(from, address(this), amount); uint256 balanceAfter = token.balanceOf(address(this)); diff --git a/contracts/Rewards/RewardsDistributor.sol b/contracts/Rewards/RewardsDistributor.sol index c19a3fe4e..667dc5328 100644 --- a/contracts/Rewards/RewardsDistributor.sol +++ b/contracts/Rewards/RewardsDistributor.sol @@ -396,11 +396,7 @@ contract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, Acce * @param supplySpeed New supply-side REWARD TOKEN speed for market * @param borrowSpeed New borrow-side REWARD TOKEN speed for market */ - function _setRewardTokenSpeed( - VToken vToken, - uint256 supplySpeed, - uint256 borrowSpeed - ) internal { + function _setRewardTokenSpeed(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal { require(comptroller.isMarketListed(vToken), "rewardToken market is not listed"); if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) { @@ -467,11 +463,7 @@ contract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, Acce * @param borrower The address of the borrower to distribute REWARD TOKEN to * @param marketBorrowIndex The current global borrow index of vToken */ - function _distributeBorrowerRewardToken( - address vToken, - address borrower, - Exp memory marketBorrowIndex - ) internal { + function _distributeBorrowerRewardToken(address vToken, address borrower, Exp memory marketBorrowIndex) internal { RewardToken storage borrowState = rewardTokenBorrowState[vToken]; uint256 borrowIndex = borrowState.index; uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower]; diff --git a/contracts/RiskFund/ProtocolShareReserve.sol b/contracts/RiskFund/ProtocolShareReserve.sol index 0b08b1d4d..bc4733c99 100644 --- a/contracts/RiskFund/ProtocolShareReserve.sol +++ b/contracts/RiskFund/ProtocolShareReserve.sol @@ -69,11 +69,7 @@ contract ProtocolShareReserve is ExponentialNoError, ReserveHelpers, IProtocolSh * @return Number of total released tokens * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero */ - function releaseFunds( - address comptroller, - address asset, - uint256 amount - ) external nonReentrant returns (uint256) { + function releaseFunds(address comptroller, address asset, uint256 amount) external nonReentrant returns (uint256) { ensureNonzeroAddress(asset); require(amount <= _poolsAssetsReserves[comptroller][asset], "ProtocolShareReserve: Insufficient pool balance"); @@ -102,10 +98,10 @@ contract ProtocolShareReserve is ExponentialNoError, ReserveHelpers, IProtocolSh * @param comptroller Comptroller address(pool) * @param asset Asset address. */ - function updateAssetsState(address comptroller, address asset) - public - override(IProtocolShareReserve, ReserveHelpers) - { + function updateAssetsState( + address comptroller, + address asset + ) public override(IProtocolShareReserve, ReserveHelpers) { super.updateAssetsState(comptroller, asset); } } diff --git a/contracts/RiskFund/RiskFund.sol b/contracts/RiskFund/RiskFund.sol index aebf91bea..3c9bf21dd 100644 --- a/contracts/RiskFund/RiskFund.sol +++ b/contracts/RiskFund/RiskFund.sol @@ -207,12 +207,10 @@ contract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, Max * @param amount Amount to be transferred to auction contract. * @return Number reserved tokens. */ - function transferReserveForAuction(address comptroller, uint256 amount) - external - override - nonReentrant - returns (uint256) - { + function transferReserveForAuction( + address comptroller, + uint256 amount + ) external override nonReentrant returns (uint256) { address shortfall_ = shortfall; require(msg.sender == shortfall_, "Risk fund: Only callable by Shortfall contract"); require( diff --git a/contracts/Shortfall/Shortfall.sol b/contracts/Shortfall/Shortfall.sol index 17c5747e6..a8e0ddf83 100644 --- a/contracts/Shortfall/Shortfall.sol +++ b/contracts/Shortfall/Shortfall.sol @@ -181,11 +181,7 @@ contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGua * @param auctionStartBlock The block number when auction started * @custom:event Emits BidPlaced event on success */ - function placeBid( - address comptroller, - uint256 bidBps, - uint256 auctionStartBlock - ) external nonReentrant { + function placeBid(address comptroller, uint256 bidBps, uint256 auctionStartBlock) external nonReentrant { Auction storage auction = auctions[comptroller]; require(auction.startBlock == auctionStartBlock, "auction has been restarted"); diff --git a/contracts/VToken.sol b/contracts/VToken.sol index 8d56450fe..527f9e5fd 100644 --- a/contracts/VToken.sol +++ b/contracts/VToken.sol @@ -142,11 +142,7 @@ contract VToken is * @custom:error TransferNotAllowed is thrown if trying to transfer to self * @custom:access Not restricted */ - function transferFrom( - address src, - address dst, - uint256 amount - ) external override nonReentrant returns (bool) { + function transferFrom(address src, address dst, uint256 amount) external override nonReentrant returns (bool) { _transferTokens(msg.sender, src, dst, amount); return true; } @@ -468,11 +464,7 @@ contract VToken is * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller * @custom:access Only Comptroller */ - function healBorrow( - address payer, - address borrower, - uint256 repayAmount - ) external override nonReentrant { + function healBorrow(address payer, address borrower, uint256 repayAmount) external override nonReentrant { if (repayAmount != 0) { comptroller.preRepayHook(address(this), borrower); } @@ -561,11 +553,7 @@ contract VToken is * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self * @custom:access Not restricted */ - function seize( - address liquidator, - address borrower, - uint256 seizeTokens - ) external override nonReentrant { + function seize(address liquidator, address borrower, uint256 seizeTokens) external override nonReentrant { _seize(msg.sender, liquidator, borrower, seizeTokens); } @@ -649,16 +637,13 @@ contract VToken is * @return borrowBalance Amount owed in terms of underlying * @return exchangeRate Stored exchange rate */ - function getAccountSnapshot(address account) + function getAccountSnapshot( + address account + ) external view override - returns ( - uint256 error, - uint256 vTokenBalance, - uint256 borrowBalance, - uint256 exchangeRate - ) + returns (uint256 error, uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRate) { return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored()); } @@ -794,11 +779,7 @@ contract VToken is * @param minter The address of the account which is supplying the assets * @param mintAmount The amount of the underlying asset to supply */ - function _mintFresh( - address payer, - address minter, - uint256 mintAmount - ) internal { + function _mintFresh(address payer, address minter, uint256 mintAmount) internal { /* Fail if mint not allowed */ comptroller.preMintHook(address(this), minter, mintAmount); @@ -851,11 +832,7 @@ contract VToken is * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero) * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero) */ - function _redeemFresh( - address redeemer, - uint256 redeemTokensIn, - uint256 redeemAmountIn - ) internal { + function _redeemFresh(address redeemer, uint256 redeemTokensIn, uint256 redeemAmountIn) internal { require(redeemTokensIn == 0 || redeemAmountIn == 0, "one of redeemTokensIn or redeemAmountIn must be zero"); /* Verify market's block number equals current block number */ @@ -985,11 +962,7 @@ contract VToken is * @param repayAmount the amount of underlying tokens being returned, or type(uint256).max for the full outstanding amount * @return (uint) the actual repayment amount. */ - function _repayBorrowFresh( - address payer, - address borrower, - uint256 repayAmount - ) internal returns (uint256) { + function _repayBorrowFresh(address payer, address borrower, uint256 repayAmount) internal returns (uint256) { /* Fail if repayBorrow not allowed */ comptroller.preRepayHook(address(this), borrower); @@ -1152,12 +1125,7 @@ contract VToken is * @param borrower The account having collateral seized * @param seizeTokens The number of vTokens to seize */ - function _seize( - address seizerContract, - address liquidator, - address borrower, - uint256 seizeTokens - ) internal { + function _seize(address seizerContract, address liquidator, address borrower, uint256 seizeTokens) internal { /* Fail if seize not allowed */ comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower); @@ -1172,7 +1140,7 @@ contract VToken is * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens */ uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller)) - .liquidationIncentiveMantissa(); + .liquidationIncentiveMantissa(); uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa })); uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa })); uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens; @@ -1361,12 +1329,7 @@ contract VToken is * @param dst The address of the destination account * @param tokens The number of tokens to transfer */ - function _transferTokens( - address spender, - address src, - address dst, - uint256 tokens - ) internal { + function _transferTokens(address spender, address src, address dst, uint256 tokens) internal { /* Fail if transfer not allowed */ comptroller.preTransferHook(address(this), src, dst, tokens); diff --git a/contracts/VTokenInterfaces.sol b/contracts/VTokenInterfaces.sol index 7b6c58f53..7483e68b8 100644 --- a/contracts/VTokenInterfaces.sol +++ b/contracts/VTokenInterfaces.sol @@ -293,11 +293,7 @@ abstract contract VTokenInterface is VTokenStorage { VTokenInterface vTokenCollateral ) external virtual returns (uint256); - function healBorrow( - address payer, - address borrower, - uint256 repayAmount - ) external virtual; + function healBorrow(address payer, address borrower, uint256 repayAmount) external virtual; function forceLiquidateBorrow( address liquidator, @@ -307,19 +303,11 @@ abstract contract VTokenInterface is VTokenStorage { bool skipCloseFactorCheck ) external virtual; - function seize( - address liquidator, - address borrower, - uint256 seizeTokens - ) external virtual; + function seize(address liquidator, address borrower, uint256 seizeTokens) external virtual; function transfer(address dst, uint256 amount) external virtual returns (bool); - function transferFrom( - address src, - address dst, - uint256 amount - ) external virtual returns (bool); + function transferFrom(address src, address dst, uint256 amount) external virtual returns (bool); function accrueInterest() external virtual returns (uint256); @@ -353,16 +341,7 @@ abstract contract VTokenInterface is VTokenStorage { function balanceOf(address owner) external view virtual returns (uint256); - function getAccountSnapshot(address account) - external - view - virtual - returns ( - uint256, - uint256, - uint256, - uint256 - ); + function getAccountSnapshot(address account) external view virtual returns (uint256, uint256, uint256, uint256); function borrowRatePerBlock() external view virtual returns (uint256); diff --git a/contracts/lib/ApproveOrRevert.sol b/contracts/lib/ApproveOrRevert.sol index c13d4460f..8ea61ae4b 100644 --- a/contracts/lib/ApproveOrRevert.sol +++ b/contracts/lib/ApproveOrRevert.sol @@ -17,11 +17,7 @@ library ApproveOrRevert { /// @param token The contract address of the token which will be transferred /// @param spender The spender contract address /// @param amount The value of the transfer - function approveOrRevert( - IERC20Upgradeable token, - address spender, - uint256 amount - ) internal { + function approveOrRevert(IERC20Upgradeable token, address spender, uint256 amount) internal { bytes memory callData = abi.encodeCall(token.approve, (spender, amount)); // solhint-disable-next-line avoid-low-level-calls diff --git a/contracts/lib/TokenDebtTracker.sol b/contracts/lib/TokenDebtTracker.sol index c183be6cc..aac79291c 100644 --- a/contracts/lib/TokenDebtTracker.sol +++ b/contracts/lib/TokenDebtTracker.sol @@ -110,11 +110,7 @@ abstract contract TokenDebtTracker is Initializable { * @param amount The amount to transfer * @custom:error InsufficientBalance The contract doesn't have enough balance to transfer */ - function _transferOutOrTrackDebt( - IERC20Upgradeable token, - address to, - uint256 amount - ) internal { + function _transferOutOrTrackDebt(IERC20Upgradeable token, address to, uint256 amount) internal { uint256 balance = token.balanceOf(address(this)); if (balance < amount) { revert InsufficientBalance(address(token), address(this), amount, balance); @@ -129,11 +125,7 @@ abstract contract TokenDebtTracker is Initializable { * @param to The recipient of the transfer * @param amount The amount to transfer */ - function _transferOutOrTrackDebtSkippingBalanceCheck( - IERC20Upgradeable token, - address to, - uint256 amount - ) internal { + function _transferOutOrTrackDebtSkippingBalanceCheck(IERC20Upgradeable token, address to, uint256 amount) internal { // We can't use safeTransfer here because we can't try-catch internal calls bool success = _tryTransferOut(token, to, amount); if (!success) { @@ -152,11 +144,7 @@ abstract contract TokenDebtTracker is Initializable { * @param amount The amount to transfer * @return true if the transfer succeeded, false otherwise */ - function _tryTransferOut( - IERC20Upgradeable token, - address to, - uint256 amount - ) private returns (bool) { + function _tryTransferOut(IERC20Upgradeable token, address to, uint256 amount) private returns (bool) { bytes memory callData = abi.encodeCall(token.transfer, (to, amount)); // solhint-disable-next-line avoid-low-level-calls diff --git a/contracts/test/ERC20.sol b/contracts/test/ERC20.sol index cabcd78c8..9dbc4d2a7 100644 --- a/contracts/test/ERC20.sol +++ b/contracts/test/ERC20.sol @@ -19,21 +19,13 @@ interface ERC20Base { abstract contract ERC20 is ERC20Base { function transfer(address to, uint256 value) external virtual returns (bool); - function transferFrom( - address from, - address to, - uint256 value - ) external virtual returns (bool); + function transferFrom(address from, address to, uint256 value) external virtual returns (bool); } abstract contract ERC20NS is ERC20Base { function transfer(address to, uint256 value) external virtual; - function transferFrom( - address from, - address to, - uint256 value - ) external virtual; + function transferFrom(address from, address to, uint256 value) external virtual; } /** @@ -51,12 +43,7 @@ contract StandardToken is ERC20 { mapping(address => mapping(address => uint256)) public override allowance; mapping(address => uint256) public override balanceOf; - constructor( - uint256 _initialAmount, - string memory _tokenName, - uint8 _decimalUnits, - string memory _tokenSymbol - ) { + constructor(uint256 _initialAmount, string memory _tokenName, uint8 _decimalUnits, string memory _tokenSymbol) { totalSupply = _initialAmount; balanceOf[msg.sender] = _initialAmount; name = _tokenName; @@ -71,11 +58,7 @@ contract StandardToken is ERC20 { return true; } - function transferFrom( - address src, - address dst, - uint256 amount - ) external virtual override returns (bool) { + function transferFrom(address src, address dst, uint256 amount) external virtual override returns (bool) { allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount, "Insufficient allowance"); balanceOf[src] = balanceOf[src].sub(amount, "Insufficient balance"); balanceOf[dst] = balanceOf[dst].add(amount, "Balance overflow"); @@ -105,12 +88,7 @@ contract NonStandardToken is ERC20NS { mapping(address => mapping(address => uint256)) public override allowance; mapping(address => uint256) public override balanceOf; - constructor( - uint256 _initialAmount, - string memory _tokenName, - uint8 _decimalUnits, - string memory _tokenSymbol - ) { + constructor(uint256 _initialAmount, string memory _tokenName, uint8 _decimalUnits, string memory _tokenSymbol) { totalSupply = _initialAmount; balanceOf[msg.sender] = _initialAmount; name = _tokenName; @@ -124,11 +102,7 @@ contract NonStandardToken is ERC20NS { emit Transfer(msg.sender, dst, amount); } - function transferFrom( - address src, - address dst, - uint256 amount - ) external override { + function transferFrom(address src, address dst, uint256 amount) external override { allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount, "Insufficient allowance"); balanceOf[src] = balanceOf[src].sub(amount, "Insufficient balance"); balanceOf[dst] = balanceOf[dst].add(amount, "Balance overflow"); @@ -173,11 +147,7 @@ contract ERC20Harness is StandardToken { return true; } - function transferFrom( - address src, - address dst, - uint256 amount - ) external override returns (bool success) { + function transferFrom(address src, address dst, uint256 amount) external override returns (bool success) { // Added for testing purposes if (failTransferFromAddresses[src]) { return false; diff --git a/contracts/test/EvilToken.sol b/contracts/test/EvilToken.sol index 6d72af717..103c751d2 100644 --- a/contracts/test/EvilToken.sol +++ b/contracts/test/EvilToken.sol @@ -37,11 +37,7 @@ contract EvilToken is FaucetToken { return true; } - function transferFrom( - address src, - address dst, - uint256 amount - ) external override returns (bool) { + function transferFrom(address src, address dst, uint256 amount) external override returns (bool) { if (fail) { return false; } diff --git a/contracts/test/FaucetToken.sol b/contracts/test/FaucetToken.sol index 93779e038..1a607c303 100644 --- a/contracts/test/FaucetToken.sol +++ b/contracts/test/FaucetToken.sol @@ -147,22 +147,14 @@ contract FaucetTokenReEntrantHarness { return true; } - function _approve( - address owner, - address spender, - uint256 amount - ) internal { + function _approve(address owner, address spender, uint256 amount) internal { require(spender != address(0), "FaucetToken: approve to the zero address"); require(owner != address(0), "FaucetToken: approve from the zero address"); allowance_[owner][spender] = amount; emit Approval(owner, spender, amount); } - function _transfer( - address src, - address dst, - uint256 amount - ) internal { + function _transfer(address src, address dst, uint256 amount) internal { require(dst != address(0), "FaucetToken: transfer to the zero address"); balanceOf_[src] = balanceOf_[src].sub(amount); balanceOf_[dst] = balanceOf_[dst].add(amount); diff --git a/contracts/test/FeeToken.sol b/contracts/test/FeeToken.sol index 67972d963..0879624d9 100644 --- a/contracts/test/FeeToken.sol +++ b/contracts/test/FeeToken.sol @@ -37,11 +37,7 @@ contract FeeToken is FaucetToken { return true; } - function transferFrom( - address src, - address dst, - uint256 amount - ) public override returns (bool) { + function transferFrom(address src, address dst, uint256 amount) public override returns (bool) { uint256 fee = amount.mul(basisPointFee).div(10000); uint256 net = amount.sub(fee); balanceOf[owner] = balanceOf[owner].add(fee); diff --git a/contracts/test/MockDeflationaryToken.sol b/contracts/test/MockDeflationaryToken.sol index 5403cf2e6..4845c3141 100644 --- a/contracts/test/MockDeflationaryToken.sol +++ b/contracts/test/MockDeflationaryToken.sol @@ -43,11 +43,7 @@ contract MockDeflatingToken { return true; } - function transferFrom( - address from, - address to, - uint256 value - ) external returns (bool) { + function transferFrom(address from, address to, uint256 value) external returns (bool) { if (allowance[from][msg.sender] != type(uint256).max) { allowance[from][msg.sender] = allowance[from][msg.sender] - value; } @@ -89,20 +85,12 @@ contract MockDeflatingToken { emit Transfer(from, address(0), value); } - function _approve( - address owner, - address spender, - uint256 value - ) private { + function _approve(address owner, address spender, uint256 value) private { allowance[owner][spender] = value; emit Approval(owner, spender, value); } - function _transfer( - address from, - address to, - uint256 value - ) private { + function _transfer(address from, address to, uint256 value) private { uint256 burnAmount = value / 100; _burn(from, burnAmount); uint256 transferAmount = value - burnAmount; diff --git a/contracts/test/Mocks/MockPancakeSwap.sol b/contracts/test/Mocks/MockPancakeSwap.sol index 6894dd396..8c7f44fae 100644 --- a/contracts/test/Mocks/MockPancakeSwap.sol +++ b/contracts/test/Mocks/MockPancakeSwap.sol @@ -10,32 +10,19 @@ pragma solidity >=0.6.0; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { - function safeApprove( - address token, - address to, - uint256 value - ) internal { + function safeApprove(address token, address to, uint256 value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: APPROVE_FAILED"); } - function safeTransfer( - address token, - address to, - uint256 value - ) internal { + function safeTransfer(address token, address to, uint256 value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FAILED"); } - function safeTransferFrom( - address token, - address from, - address to, - uint256 value - ) internal { + function safeTransferFrom(address token, address from, address to, uint256 value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FROM_FAILED"); @@ -67,13 +54,7 @@ interface IPancakeRouter01 { uint256 amountBMin, address to, uint256 deadline - ) - external - returns ( - uint256 amountA, - uint256 amountB, - uint256 liquidity - ); + ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity); function addLiquidityETH( address token, @@ -82,14 +63,7 @@ interface IPancakeRouter01 { uint256 amountETHMin, address to, uint256 deadline - ) - external - payable - returns ( - uint256 amountToken, - uint256 amountETH, - uint256 liquidity - ); + ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity); function removeLiquidity( address tokenA, @@ -183,11 +157,7 @@ interface IPancakeRouter01 { uint256 deadline ) external payable returns (uint256[] memory amounts); - function quote( - uint256 amountA, - uint256 reserveA, - uint256 reserveB - ) external pure returns (uint256 amountB); + function quote(uint256 amountA, uint256 reserveA, uint256 reserveB) external pure returns (uint256 amountB); function getAmountOut( uint256 amountIn, @@ -335,11 +305,7 @@ interface IPancakePair { function transfer(address to, uint256 value) external returns (bool); - function transferFrom( - address from, - address to, - uint256 value - ) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); @@ -377,14 +343,7 @@ interface IPancakePair { function token1() external view returns (address); - function getReserves() - external - view - returns ( - uint112 reserve0, - uint112 reserve1, - uint32 blockTimestampLast - ); + function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint256); @@ -396,12 +355,7 @@ interface IPancakePair { function burn(address to) external returns (uint256 amount0, uint256 amount1); - function swap( - uint256 amount0Out, - uint256 amount1Out, - address to, - bytes calldata data - ) external; + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; function skim(address to) external; @@ -427,11 +381,7 @@ library PancakeLibrary { } // calculates the CREATE2 address for a pair without making any external calls - function pairFor( - address factory, - address tokenA, - address tokenB - ) internal pure returns (address pair) { + function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); pair = address( uint256( @@ -461,11 +411,7 @@ library PancakeLibrary { } // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset - function quote( - uint256 amountA, - uint256 reserveA, - uint256 reserveB - ) internal pure returns (uint256 amountB) { + function quote(uint256 amountA, uint256 reserveA, uint256 reserveB) internal pure returns (uint256 amountB) { require(amountA > 0, "PancakeLibrary: INSUFFICIENT_AMOUNT"); require(reserveA > 0 && reserveB > 0, "PancakeLibrary: INSUFFICIENT_LIQUIDITY"); amountB = amountA.mul(reserveB) / reserveA; @@ -555,11 +501,7 @@ interface IERC20 { function transfer(address to, uint256 value) external returns (bool); - function transferFrom( - address from, - address to, - uint256 value - ) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); } // File: contracts\interfaces\IWETH.sol @@ -641,17 +583,7 @@ contract PancakeRouter is IPancakeRouter02 { uint256 amountBMin, address to, uint256 deadline - ) - external - virtual - override - ensure(deadline) - returns ( - uint256 amountA, - uint256 amountB, - uint256 liquidity - ) - { + ) external virtual override ensure(deadline) returns (uint256 amountA, uint256 amountB, uint256 liquidity) { (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin); address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB); TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA); @@ -672,11 +604,7 @@ contract PancakeRouter is IPancakeRouter02 { virtual override ensure(deadline) - returns ( - uint256 amountToken, - uint256 amountETH, - uint256 liquidity - ) + returns (uint256 amountToken, uint256 amountETH, uint256 liquidity) { (amountToken, amountETH) = _addLiquidity( token, @@ -815,11 +743,7 @@ contract PancakeRouter is IPancakeRouter02 { // **** SWAP **** // requires the initial amount to have already been sent to the first pair - function _swap( - uint256[] memory amounts, - address[] memory path, - address _to - ) internal virtual { + function _swap(uint256[] memory amounts, address[] memory path, address _to) internal virtual { for (uint256 i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); PancakeLibrary.sortTokens(input, output); @@ -1047,23 +971,17 @@ contract PancakeRouter is IPancakeRouter02 { return PancakeLibrary.getAmountIn(amountOut, reserveIn, reserveOut); } - function getAmountsOut(uint256 amountIn, address[] memory path) - public - view - virtual - override - returns (uint256[] memory amounts) - { + function getAmountsOut( + uint256 amountIn, + address[] memory path + ) public view virtual override returns (uint256[] memory amounts) { return PancakeLibrary.getAmountsOut(factory, amountIn, path); } - function getAmountsIn(uint256 amountOut, address[] memory path) - public - view - virtual - override - returns (uint256[] memory amounts) - { + function getAmountsIn( + uint256 amountOut, + address[] memory path + ) public view virtual override returns (uint256[] memory amounts) { return PancakeLibrary.getAmountsIn(factory, amountOut, path); } } diff --git a/contracts/test/Mocks/MockToken.sol b/contracts/test/Mocks/MockToken.sol index 2615a27d4..ced5e3e4f 100644 --- a/contracts/test/Mocks/MockToken.sol +++ b/contracts/test/Mocks/MockToken.sol @@ -8,11 +8,7 @@ import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MockToken is ERC20 { uint8 private immutable _decimals; - constructor( - string memory name_, - string memory symbol_, - uint8 decimals_ - ) ERC20(name_, symbol_) { + constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20(name_, symbol_) { _decimals = decimals_; } diff --git a/contracts/test/SafeMath.sol b/contracts/test/SafeMath.sol index 33ca62cf2..569e8e8a7 100644 --- a/contracts/test/SafeMath.sol +++ b/contracts/test/SafeMath.sol @@ -44,11 +44,7 @@ library SafeMath { * Requirements: * - Addition cannot overflow. */ - function add( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { + function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { uint256 c; unchecked { c = a + b; @@ -78,11 +74,7 @@ library SafeMath { * Requirements: * - Subtraction cannot underflow. */ - function sub( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; @@ -122,11 +114,7 @@ library SafeMath { * Requirements: * - Multiplication cannot overflow. */ - function mul( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { + function mul(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 @@ -169,11 +157,7 @@ library SafeMath { * Requirements: * - The divisor cannot be zero. */ - function div( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; @@ -208,11 +192,7 @@ library SafeMath { * Requirements: * - The divisor cannot be zero. */ - function mod( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } diff --git a/contracts/test/VTokenHarness.sol b/contracts/test/VTokenHarness.sol index cc91adade..3690c212e 100644 --- a/contracts/test/VTokenHarness.sol +++ b/contracts/test/VTokenHarness.sol @@ -41,11 +41,7 @@ contract VTokenHarness is VToken { totalReserves = totalReserves_; } - function harnessExchangeRateDetails( - uint256 totalSupply_, - uint256 totalBorrows_, - uint256 totalReserves_ - ) external { + function harnessExchangeRateDetails(uint256 totalSupply_, uint256 totalBorrows_, uint256 totalReserves_) external { totalSupply = totalSupply_; totalBorrows = totalBorrows_; totalReserves = totalReserves_; @@ -64,19 +60,11 @@ contract VTokenHarness is VToken { super._mintFresh(account, account, mintAmount); } - function harnessRedeemFresh( - address payable account, - uint256 vTokenAmount, - uint256 underlyingAmount - ) external { + function harnessRedeemFresh(address payable account, uint256 vTokenAmount, uint256 underlyingAmount) external { super._redeemFresh(account, vTokenAmount, underlyingAmount); } - function harnessSetAccountBorrows( - address account, - uint256 principal, - uint256 interestIndex - ) external { + function harnessSetAccountBorrows(address account, uint256 principal, uint256 interestIndex) external { accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex }); } @@ -88,11 +76,7 @@ contract VTokenHarness is VToken { _borrowFresh(account, borrowAmount); } - function harnessRepayBorrowFresh( - address payer, - address account, - uint256 repayAmount - ) external { + function harnessRepayBorrowFresh(address payer, address account, uint256 repayAmount) external { _repayBorrowFresh(payer, account, repayAmount); } diff --git a/contracts/test/lib/ApproveOrRevertHarness.sol b/contracts/test/lib/ApproveOrRevertHarness.sol index b0d3185a3..e590d90b6 100644 --- a/contracts/test/lib/ApproveOrRevertHarness.sol +++ b/contracts/test/lib/ApproveOrRevertHarness.sol @@ -8,11 +8,7 @@ import { ApproveOrRevert } from "../../lib/ApproveOrRevert.sol"; contract ApproveOrRevertHarness { using ApproveOrRevert for IERC20Upgradeable; - function approve( - IERC20Upgradeable token, - address spender, - uint256 amount - ) external { + function approve(IERC20Upgradeable token, address spender, uint256 amount) external { token.approveOrRevert(spender, amount); } } diff --git a/contracts/test/lib/TokenDebtTrackerHarness.sol b/contracts/test/lib/TokenDebtTrackerHarness.sol index 4b8747689..37e8f7282 100644 --- a/contracts/test/lib/TokenDebtTrackerHarness.sol +++ b/contracts/test/lib/TokenDebtTrackerHarness.sol @@ -10,20 +10,12 @@ contract TokenDebtTrackerHarness is TokenDebtTracker { __TokenDebtTracker_init(); } - function addTokenDebt( - IERC20Upgradeable token, - address user, - uint256 amount - ) external { + function addTokenDebt(IERC20Upgradeable token, address user, uint256 amount) external { tokenDebt[token][user] += amount; totalTokenDebt[token] += amount; } - function transferOutOrTrackDebt( - IERC20Upgradeable token, - address user, - uint256 amount - ) external { + function transferOutOrTrackDebt(IERC20Upgradeable token, address user, uint256 amount) external { _transferOutOrTrackDebt(token, user, amount); } diff --git a/package.json b/package.json index d3ed836a8..4355cfa71 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "hardhat-gas-reporter": "^1.0.8", "husky": "^8.0.1", "prettier": "2.7.1", - "prettier-plugin-solidity": "1.0.0-beta.13", + "prettier-plugin-solidity": "1.1.3", "semantic-release": "^19.0.3", "solhint": "^3.3.7", "solidity-coverage": "^0.8.4", diff --git a/spec/certora/contracts/CErc20DelegateCertora.sol b/spec/certora/contracts/CErc20DelegateCertora.sol index cf6d40e6a..11ac936e9 100644 --- a/spec/certora/contracts/CErc20DelegateCertora.sol +++ b/spec/certora/contracts/CErc20DelegateCertora.sol @@ -25,11 +25,7 @@ contract VBep20DelegateCertora is VBep20Delegate { return borrowFresh(borrower, borrowAmount); } - function repayBorrowFreshPub( - address payer, - address borrower, - uint256 repayAmount - ) public returns (uint256) { + function repayBorrowFreshPub(address payer, address borrower, uint256 repayAmount) public returns (uint256) { (uint256 error, ) = repayBorrowFresh(payer, borrower, repayAmount); return error; } diff --git a/spec/certora/contracts/CErc20DelegatorCertora.sol b/spec/certora/contracts/CErc20DelegatorCertora.sol index 1e1219ce9..dccde1712 100644 --- a/spec/certora/contracts/CErc20DelegatorCertora.sol +++ b/spec/certora/contracts/CErc20DelegatorCertora.sol @@ -108,11 +108,7 @@ contract VBep20DelegatorCertora is VBep20Delegator { return abi.decode(data, (uint256)); } - function repayBorrowFreshPub( - address payer, - address borrower, - uint256 repayAmount - ) public returns (uint256) { + function repayBorrowFreshPub(address payer, address borrower, uint256 repayAmount) public returns (uint256) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("_repayBorrowFreshPub(address,address,uint256)", payer, borrower, repayAmount) ); diff --git a/spec/certora/contracts/CErc20ImmutableCertora.sol b/spec/certora/contracts/CErc20ImmutableCertora.sol index 3688425a2..7136a5a94 100644 --- a/spec/certora/contracts/CErc20ImmutableCertora.sol +++ b/spec/certora/contracts/CErc20ImmutableCertora.sol @@ -88,11 +88,7 @@ contract VBep20ImmutableCertora is VBep20Immutable { return borrowFresh(borrower, borrowAmount); } - function repayBorrowFreshPub( - address payer, - address borrower, - uint256 repayAmount - ) public returns (uint256) { + function repayBorrowFreshPub(address payer, address borrower, uint256 repayAmount) public returns (uint256) { (uint256 error, ) = repayBorrowFresh(payer, borrower, repayAmount); return error; } diff --git a/spec/certora/contracts/ComptrollerCertora.sol b/spec/certora/contracts/ComptrollerCertora.sol index 784bf9987..498fc2836 100644 --- a/spec/certora/contracts/ComptrollerCertora.sol +++ b/spec/certora/contracts/ComptrollerCertora.sol @@ -11,16 +11,7 @@ contract ComptrollerCertora is Comptroller { VToken vTokenModify, uint256 redeemTokens, uint256 borrowAmount - ) - internal - view - override - returns ( - Error, - uint256, - uint256 - ) - { + ) internal view override returns (Error, uint256, uint256) { if (switcher == 0) return (Error.NO_ERROR, liquidityOrShortfall, 0); if (switcher == 1) return (Error.NO_ERROR, 0, liquidityOrShortfall); if (switcher == 2) return (Error.SNAPSHOT_ERROR, 0, 0); diff --git a/spec/certora/contracts/TimelockCertora.sol b/spec/certora/contracts/TimelockCertora.sol index 22643fb50..dafb2429f 100644 --- a/spec/certora/contracts/TimelockCertora.sol +++ b/spec/certora/contracts/TimelockCertora.sol @@ -9,27 +9,15 @@ contract TimelockCertora is Timelock { return GRACE_PERIOD; } - function queueTransactionStatic( - address target, - uint256 value, - uint256 eta - ) public returns (bytes32) { + function queueTransactionStatic(address target, uint256 value, uint256 eta) public returns (bytes32) { return queueTransaction(target, value, "setCounter()", "", eta); } - function cancelTransactionStatic( - address target, - uint256 value, - uint256 eta - ) public { + function cancelTransactionStatic(address target, uint256 value, uint256 eta) public { return cancelTransaction(target, value, "setCounter()", "", eta); } - function executeTransactionStatic( - address target, - uint256 value, - uint256 eta - ) public { + function executeTransactionStatic(address target, uint256 value, uint256 eta) public { executeTransaction(target, value, "setCounter()", "", eta); // NB: cannot return dynamic types (will hang solver) } } diff --git a/spec/certora/contracts/UnderlyingModelNonStandard.sol b/spec/certora/contracts/UnderlyingModelNonStandard.sol index 518bdda29..827fe0601 100644 --- a/spec/certora/contracts/UnderlyingModelNonStandard.sol +++ b/spec/certora/contracts/UnderlyingModelNonStandard.sol @@ -26,11 +26,7 @@ contract UnderlyingModelNonStandard is EIP20NonStandardInterface, SimulationInte balances[dst] += amount; } - function transferFrom( - address src, - address dst, - uint256 amount - ) external override { + function transferFrom(address src, address dst, uint256 amount) external override { require(allowances[src][msg.sender] >= amount); require(balances[src] >= amount); require(balances[dst] + amount >= balances[dst]); diff --git a/spec/certora/contracts/UnderlyingModelWithFee.sol b/spec/certora/contracts/UnderlyingModelWithFee.sol index 55a98a755..ec70e632f 100644 --- a/spec/certora/contracts/UnderlyingModelWithFee.sol +++ b/spec/certora/contracts/UnderlyingModelWithFee.sol @@ -29,11 +29,7 @@ contract UnderlyingModelWithFee is EIP20NonStandardInterface, SimulationInterfac balances[dst] += actualAmount; } - function transferFrom( - address src, - address dst, - uint256 amount - ) external override { + function transferFrom(address src, address dst, uint256 amount) external override { uint256 actualAmount = amount + fee; require(actualAmount > fee); require(allowances[src][msg.sender] >= actualAmount); diff --git a/spec/certora/contracts/mcd/Dai.sol b/spec/certora/contracts/mcd/Dai.sol index 9069033cc..7708645af 100644 --- a/spec/certora/contracts/mcd/Dai.sol +++ b/spec/certora/contracts/mcd/Dai.sol @@ -80,11 +80,7 @@ contract Dai is LibNote { return transferFrom(msg.sender, dst, wad); } - function transferFrom( - address src, - address dst, - uint256 wad - ) public returns (bool) { + function transferFrom(address src, address dst, uint256 wad) public returns (bool) { require(balanceOf[src] >= wad, "Dai/insufficient-balance"); if (src != msg.sender && allowance[src][msg.sender] != uint256(-1)) { require(allowance[src][msg.sender] >= wad, "Dai/insufficient-allowance"); @@ -128,11 +124,7 @@ contract Dai is LibNote { transferFrom(usr, msg.sender, wad); } - function move( - address src, - address dst, - uint256 wad - ) external { + function move(address src, address dst, uint256 wad) external { transferFrom(src, dst, wad); } diff --git a/spec/certora/contracts/mcd/Pot.sol b/spec/certora/contracts/mcd/Pot.sol index e72532bba..9d1663c26 100644 --- a/spec/certora/contracts/mcd/Pot.sol +++ b/spec/certora/contracts/mcd/Pot.sol @@ -39,17 +39,9 @@ import "./lib.sol"; */ contract VatLike { - function move( - address, - address, - uint256 - ) external; - - function suck( - address, - address, - uint256 - ) external; + function move(address, address, uint256) external; + + function suck(address, address, uint256) external; } contract Pot is LibNote { @@ -93,13 +85,9 @@ contract Pot is LibNote { } // --- Math --- - uint256 constant ONE = 10**27; + uint256 constant ONE = 10 ** 27; - function rpow( - uint256 x, - uint256 n, - uint256 base - ) internal pure returns (uint256 z) { + function rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) { assembly { switch x case 0 { diff --git a/spec/certora/contracts/mcd/Vat.sol b/spec/certora/contracts/mcd/Vat.sol index 6a7470de0..28616e205 100644 --- a/spec/certora/contracts/mcd/Vat.sol +++ b/spec/certora/contracts/mcd/Vat.sol @@ -144,7 +144,7 @@ contract Vat { // --- Administration --- function init(bytes32 ilk) external note auth { require(ilks[ilk].rate == 0, "Vat/ilk-already-init"); - ilks[ilk].rate = 10**27; + ilks[ilk].rate = 10 ** 27; } function file(bytes32 what, uint256 data) external note auth { @@ -153,11 +153,7 @@ contract Vat { else revert("Vat/file-unrecognized-param"); } - function file( - bytes32 ilk, - bytes32 what, - uint256 data - ) external note auth { + function file(bytes32 ilk, bytes32 what, uint256 data) external note auth { require(live == 1, "Vat/not-live"); if (what == "spot") ilks[ilk].spot = data; else if (what == "line") ilks[ilk].line = data; @@ -170,30 +166,17 @@ contract Vat { } // --- Fungibility --- - function slip( - bytes32 ilk, - address usr, - int256 wad - ) external note auth { + function slip(bytes32 ilk, address usr, int256 wad) external note auth { gem[ilk][usr] = add(gem[ilk][usr], wad); } - function flux( - bytes32 ilk, - address src, - address dst, - uint256 wad - ) external note { + function flux(bytes32 ilk, address src, address dst, uint256 wad) external note { require(wish(src, msg.sender), "Vat/not-allowed"); gem[ilk][src] = sub(gem[ilk][src], wad); gem[ilk][dst] = add(gem[ilk][dst], wad); } - function move( - address src, - address dst, - uint256 rad - ) external note { + function move(address src, address dst, uint256 rad) external note { require(wish(src, msg.sender), "Vat/not-allowed"); dai[src] = sub(dai[src], rad); dai[dst] = add(dai[dst], rad); @@ -212,14 +195,7 @@ contract Vat { } // --- CDP Manipulation --- - function frob( - bytes32 i, - address u, - address v, - address w, - int256 dink, - int256 dart - ) external note { + function frob(bytes32 i, address u, address v, address w, int256 dink, int256 dart) external note { // system is live require(live == 1, "Vat/not-live"); @@ -259,13 +235,7 @@ contract Vat { } // --- CDP Fungibility --- - function fork( - bytes32 ilk, - address src, - address dst, - int256 dink, - int256 dart - ) external note { + function fork(bytes32 ilk, address src, address dst, int256 dink, int256 dart) external note { Urn storage u = urns[ilk][src]; Urn storage v = urns[ilk][dst]; Ilk storage i = ilks[ilk]; @@ -291,14 +261,7 @@ contract Vat { } // --- CDP Confiscation --- - function grab( - bytes32 i, - address u, - address v, - address w, - int256 dink, - int256 dart - ) external note auth { + function grab(bytes32 i, address u, address v, address w, int256 dink, int256 dart) external note auth { Urn storage urn = urns[i][u]; Ilk storage ilk = ilks[i]; @@ -322,11 +285,7 @@ contract Vat { debt = sub(debt, rad); } - function suck( - address u, - address v, - uint256 rad - ) external note auth { + function suck(address u, address v, uint256 rad) external note auth { sin[u] = add(sin[u], rad); dai[v] = add(dai[v], rad); vice = add(vice, rad); @@ -334,11 +293,7 @@ contract Vat { } // --- Rates --- - function fold( - bytes32 i, - address u, - int256 rate - ) external note auth { + function fold(bytes32 i, address u, int256 rate) external note auth { require(live == 1, "Vat/not-live"); Ilk storage ilk = ilks[i]; ilk.rate = add(ilk.rate, rate); diff --git a/spec/certora/contracts/mcd/join.sol b/spec/certora/contracts/mcd/join.sol index 40bdef556..ff443970e 100644 --- a/spec/certora/contracts/mcd/join.sol +++ b/spec/certora/contracts/mcd/join.sol @@ -24,11 +24,7 @@ contract GemLike { function transfer(address, uint256) external returns (bool); - function transferFrom( - address, - address, - uint256 - ) external returns (bool); + function transferFrom(address, address, uint256) external returns (bool); } contract DSTokenLike { @@ -38,17 +34,9 @@ contract DSTokenLike { } contract VatLike { - function slip( - bytes32, - address, - int256 - ) external; - - function move( - address, - address, - uint256 - ) external; + function slip(bytes32, address, int256) external; + + function move(address, address, uint256) external; } /* @@ -98,11 +86,7 @@ contract GemJoin is LibNote { uint256 public dec; uint256 public live; // Access Flag - constructor( - address vat_, - bytes32 ilk_, - address gem_ - ) public { + constructor(address vat_, bytes32 ilk_, address gem_) public { wards[msg.sender] = 1; live = 1; vat = VatLike(vat_); @@ -123,7 +107,7 @@ contract GemJoin is LibNote { } function exit(address usr, uint256 wad) external note { - require(wad <= 2**255, "GemJoin/overflow"); + require(wad <= 2 ** 255, "GemJoin/overflow"); vat.slip(ilk, msg.sender, -int256(wad)); require(gem.transfer(usr, wad), "GemJoin/failed-transfer"); } @@ -206,7 +190,7 @@ contract DaiJoin is LibNote { live = 0; } - uint256 constant ONE = 10**27; + uint256 constant ONE = 10 ** 27; function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x); diff --git a/yarn.lock b/yarn.lock index 07c804a9c..d61d00fe9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2984,7 +2984,7 @@ __metadata: husky: ^8.0.1 module-alias: ^2.2.2 prettier: 2.7.1 - prettier-plugin-solidity: 1.0.0-beta.13 + prettier-plugin-solidity: 1.1.3 semantic-release: ^19.0.3 solhint: ^3.3.7 solidity-coverage: ^0.8.4 @@ -10242,19 +10242,16 @@ __metadata: languageName: node linkType: hard -"prettier-plugin-solidity@npm:1.0.0-beta.13": - version: 1.0.0-beta.13 - resolution: "prettier-plugin-solidity@npm:1.0.0-beta.13" +"prettier-plugin-solidity@npm:1.1.3": + version: 1.1.3 + resolution: "prettier-plugin-solidity@npm:1.1.3" dependencies: - "@solidity-parser/parser": ^0.13.2 - emoji-regex: ^9.2.2 - escape-string-regexp: ^4.0.0 - semver: ^7.3.5 + "@solidity-parser/parser": ^0.16.0 + semver: ^7.3.8 solidity-comments-extractor: ^0.0.7 - string-width: ^4.2.2 peerDependencies: - prettier: ^2.3.0 - checksum: 253de4255f3e9f64b88dbc2a2d8de595090ff10eb9dca845b58632d9ce71d23f5e1954864d0e5542a34d103aa0f4d1a1a9267a7a7dea3e5dfbe41f1f7bf9cbcf + prettier: ">=2.3.0 || >=3.0.0-alpha.0" + checksum: d5aadfa411a4d983a2bd204048726fd91fbcaffbfa26d818ef0d6001fb65f82d0eae082e935e96c79e65e09ed979b186311ddb8c38be2f0ce5dd5f5265df77fe languageName: node linkType: hard @@ -11108,7 +11105,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8": version: 7.5.4 resolution: "semver@npm:7.5.4" dependencies: @@ -11620,7 +11617,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: From 8e84e21044afe56e4523dc2e57e428c5a9b7bde8 Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Thu, 7 Sep 2023 08:00:13 +0000 Subject: [PATCH 26/39] chore(release): 2.0.0 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [2.0.0](https://github.com/VenusProtocol/isolated-pools/compare/v1.3.0...v2.0.0) (2023-09-07) ### ⚠ BREAKING CHANGES * [RHR-01] make poolsAssetsReserves internal * align the gap in reserve helpers ### Features * add a balance check to graceful transfer ([03370b9](https://github.com/VenusProtocol/isolated-pools/commit/03370b97fa767fc763fad157bd08e6158e441fbb)) * add deployment info for the last rewards in the LSB pool ([5e8a082](https://github.com/VenusProtocol/isolated-pools/commit/5e8a08218984caed92fb6591f03c53648478f8ea)) * add mainnet deployment ([3b29e3e](https://github.com/VenusProtocol/isolated-pools/commit/3b29e3e591078cab0aaf868b4187f735fa9a61db)) * add re-entrancy guard ([80c7435](https://github.com/VenusProtocol/isolated-pools/commit/80c74352e317d33df17daa95943c85f7648a35b4)) * add testnet deployment of new market in DeFi pool ([8c9053f](https://github.com/VenusProtocol/isolated-pools/commit/8c9053f75a8f0f3c0bf082cdb75a01a44ef29ca3)) * avoid locking on failed transfers to previous bidders ([a689850](https://github.com/VenusProtocol/isolated-pools/commit/a6898500d17e41a8db4e3bdd03e5feaf1cae5a63)) * deploy HAY rewards distributor ([30325ea](https://github.com/VenusProtocol/isolated-pools/commit/30325ea4a680f2b81457ce7f72f857292ccf18bf)) * deployed SD Rewards distributor ([98b514d](https://github.com/VenusProtocol/isolated-pools/commit/98b514dc49b38c3a37eaf9a8d69081ffdd7d7516)) * export ankrBNB market deployment ([ec43dd8](https://github.com/VenusProtocol/isolated-pools/commit/ec43dd8d2efd2eece7494f143089a9506d40ad14)) * set risk fund percentage to 50% ([4ff68c0](https://github.com/VenusProtocol/isolated-pools/commit/4ff68c088bf83fe029b76016399f1a5bf1733631)) * support deadline in swapPoolsAssets ([103be13](https://github.com/VenusProtocol/isolated-pools/commit/103be136015e45d88086a8e001bf7f01cc767fff)) * update base asset price before querying ([a2cb18a](https://github.com/VenusProtocol/isolated-pools/commit/a2cb18a74db663cb79890aa4d5891d840be32769)) * upgrade HAY rewards distributor on bsctestnet ([12dceac](https://github.com/VenusProtocol/isolated-pools/commit/12dceac5746d38654539453ffbdcef2ec3a8efb0)) * ven-1567 add sweep token function ([192a19d](https://github.com/VenusProtocol/isolated-pools/commit/192a19db17bef9e2f51c041b77abc6ff7077973e)) * ven-1743 Risk Fund ([7413501](https://github.com/VenusProtocol/isolated-pools/commit/7413501ac5210ff5e688d353f383aaf4e057a3c6)) ### Bug Fixes * [RFR-01][RFR-03] unify the meaning of minAmountToConvert ([db0e468](https://github.com/VenusProtocol/isolated-pools/commit/db0e468de1fc0f536e05d0a716b6572c60a28c53)) * [SSV-01] use _transferOutOrTrackDebt upon closing the auction ([5ca628c](https://github.com/VenusProtocol/isolated-pools/commit/5ca628c1a94abe654d8cc7461e0fe920898f808c)) * [VPB-04] fix potential re-entrancy issues ([42a9f78](https://github.com/VenusProtocol/isolated-pools/commit/42a9f78dbe59afa8477235f8a9be20bcacad6b7c)) * added SD rewards distributor ([ed4ed8a](https://github.com/VenusProtocol/isolated-pools/commit/ed4ed8a3a26620d06143cf9912889cb82bb35cd9)) * allow reward distributor with same reward token ([7603b4e](https://github.com/VenusProtocol/isolated-pools/commit/7603b4ed84040dd883aa3a8f411dd2d2d1fb4956)) * comments ([fecd4bb](https://github.com/VenusProtocol/isolated-pools/commit/fecd4bb093ff267c1ba5ec03cf574a9c0e137828)) * deployed latest comptroller ([3599ed4](https://github.com/VenusProtocol/isolated-pools/commit/3599ed40c6c10f1f09df2d7288566eccb7c6e2a2)) * deployed reward distributors for mainnet and testnet ([2aedd92](https://github.com/VenusProtocol/isolated-pools/commit/2aedd92714a101d2ce8d255ab24051049d647ed3)) * fix deployment of comptroller and verification ([50d6edd](https://github.com/VenusProtocol/isolated-pools/commit/50d6edd8e6184407777eeb8fc281fe3862a7988c)) * fixed tests ([83c1c3b](https://github.com/VenusProtocol/isolated-pools/commit/83c1c3b5a52c383241373dce676bab4c3b9e3fb5)) * gas optimisation + correct state update in transferReserveForAuction ([5dc8120](https://github.com/VenusProtocol/isolated-pools/commit/5dc81207394f80b35a9923ef5d6ea4ee65073996)) * include reward token in event ([b5b1558](https://github.com/VenusProtocol/isolated-pools/commit/b5b1558ef375adde0892343e4caed0ad18b6a045)) * lint ([ba43cef](https://github.com/VenusProtocol/isolated-pools/commit/ba43cef02cbf28995d0b7834b365eb1e6b907ac6)) * lint issues ([2cc0f29](https://github.com/VenusProtocol/isolated-pools/commit/2cc0f29baebc822280a65257b1feae061c4d729e)) * redeployed HAY reward distributors ([5c62416](https://github.com/VenusProtocol/isolated-pools/commit/5c62416d2fa791be949c7d37b0490ca221a87e9d)) * revert on approval failures ([6c559f1](https://github.com/VenusProtocol/isolated-pools/commit/6c559f1b31bd3b9ab1e8ff4023353e54308f8210)) * set the last reward distributor deployed for HAY ([0955403](https://github.com/VenusProtocol/isolated-pools/commit/09554032ca5ed3b04db228d5359a2e4db2fa8fd3)) * update assetsReserves mapping for every swap ([3427b24](https://github.com/VenusProtocol/isolated-pools/commit/3427b24382f6a59d8c132701afe9c2bd0c62d881)) * update method signature in access control check ([e4820ff](https://github.com/VenusProtocol/isolated-pools/commit/e4820ff035e06c5d83caa1397b28dd3ca3cc64a5)) * ven-1817 pve003 ([f603afd](https://github.com/VenusProtocol/isolated-pools/commit/f603afd7071c495971690e39f1bc4d59eb4df964)) ### Code Refactoring * [RHR-01] make poolsAssetsReserves internal ([9085787](https://github.com/VenusProtocol/isolated-pools/commit/908578705a8ab2cb6058bca205a6af3083895c13)) * align the gap in reserve helpers ([c47d6c0](https://github.com/VenusProtocol/isolated-pools/commit/c47d6c076b5caac4f544f1c8a499056d5f7f7eca)) --- CHANGELOG.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24f240080..756a6884b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,59 @@ +## [2.0.0](https://github.com/VenusProtocol/isolated-pools/compare/v1.3.0...v2.0.0) (2023-09-07) + + +### ⚠ BREAKING CHANGES + +* [RHR-01] make poolsAssetsReserves internal +* align the gap in reserve helpers + +### Features + +* add a balance check to graceful transfer ([03370b9](https://github.com/VenusProtocol/isolated-pools/commit/03370b97fa767fc763fad157bd08e6158e441fbb)) +* add deployment info for the last rewards in the LSB pool ([5e8a082](https://github.com/VenusProtocol/isolated-pools/commit/5e8a08218984caed92fb6591f03c53648478f8ea)) +* add mainnet deployment ([3b29e3e](https://github.com/VenusProtocol/isolated-pools/commit/3b29e3e591078cab0aaf868b4187f735fa9a61db)) +* add re-entrancy guard ([80c7435](https://github.com/VenusProtocol/isolated-pools/commit/80c74352e317d33df17daa95943c85f7648a35b4)) +* add testnet deployment of new market in DeFi pool ([8c9053f](https://github.com/VenusProtocol/isolated-pools/commit/8c9053f75a8f0f3c0bf082cdb75a01a44ef29ca3)) +* avoid locking on failed transfers to previous bidders ([a689850](https://github.com/VenusProtocol/isolated-pools/commit/a6898500d17e41a8db4e3bdd03e5feaf1cae5a63)) +* deploy HAY rewards distributor ([30325ea](https://github.com/VenusProtocol/isolated-pools/commit/30325ea4a680f2b81457ce7f72f857292ccf18bf)) +* deployed SD Rewards distributor ([98b514d](https://github.com/VenusProtocol/isolated-pools/commit/98b514dc49b38c3a37eaf9a8d69081ffdd7d7516)) +* export ankrBNB market deployment ([ec43dd8](https://github.com/VenusProtocol/isolated-pools/commit/ec43dd8d2efd2eece7494f143089a9506d40ad14)) +* set risk fund percentage to 50% ([4ff68c0](https://github.com/VenusProtocol/isolated-pools/commit/4ff68c088bf83fe029b76016399f1a5bf1733631)) +* support deadline in swapPoolsAssets ([103be13](https://github.com/VenusProtocol/isolated-pools/commit/103be136015e45d88086a8e001bf7f01cc767fff)) +* update base asset price before querying ([a2cb18a](https://github.com/VenusProtocol/isolated-pools/commit/a2cb18a74db663cb79890aa4d5891d840be32769)) +* upgrade HAY rewards distributor on bsctestnet ([12dceac](https://github.com/VenusProtocol/isolated-pools/commit/12dceac5746d38654539453ffbdcef2ec3a8efb0)) +* ven-1567 add sweep token function ([192a19d](https://github.com/VenusProtocol/isolated-pools/commit/192a19db17bef9e2f51c041b77abc6ff7077973e)) +* ven-1743 Risk Fund ([7413501](https://github.com/VenusProtocol/isolated-pools/commit/7413501ac5210ff5e688d353f383aaf4e057a3c6)) + + +### Bug Fixes + +* [RFR-01][RFR-03] unify the meaning of minAmountToConvert ([db0e468](https://github.com/VenusProtocol/isolated-pools/commit/db0e468de1fc0f536e05d0a716b6572c60a28c53)) +* [SSV-01] use _transferOutOrTrackDebt upon closing the auction ([5ca628c](https://github.com/VenusProtocol/isolated-pools/commit/5ca628c1a94abe654d8cc7461e0fe920898f808c)) +* [VPB-04] fix potential re-entrancy issues ([42a9f78](https://github.com/VenusProtocol/isolated-pools/commit/42a9f78dbe59afa8477235f8a9be20bcacad6b7c)) +* added SD rewards distributor ([ed4ed8a](https://github.com/VenusProtocol/isolated-pools/commit/ed4ed8a3a26620d06143cf9912889cb82bb35cd9)) +* allow reward distributor with same reward token ([7603b4e](https://github.com/VenusProtocol/isolated-pools/commit/7603b4ed84040dd883aa3a8f411dd2d2d1fb4956)) +* comments ([fecd4bb](https://github.com/VenusProtocol/isolated-pools/commit/fecd4bb093ff267c1ba5ec03cf574a9c0e137828)) +* deployed latest comptroller ([3599ed4](https://github.com/VenusProtocol/isolated-pools/commit/3599ed40c6c10f1f09df2d7288566eccb7c6e2a2)) +* deployed reward distributors for mainnet and testnet ([2aedd92](https://github.com/VenusProtocol/isolated-pools/commit/2aedd92714a101d2ce8d255ab24051049d647ed3)) +* fix deployment of comptroller and verification ([50d6edd](https://github.com/VenusProtocol/isolated-pools/commit/50d6edd8e6184407777eeb8fc281fe3862a7988c)) +* fixed tests ([83c1c3b](https://github.com/VenusProtocol/isolated-pools/commit/83c1c3b5a52c383241373dce676bab4c3b9e3fb5)) +* gas optimisation + correct state update in transferReserveForAuction ([5dc8120](https://github.com/VenusProtocol/isolated-pools/commit/5dc81207394f80b35a9923ef5d6ea4ee65073996)) +* include reward token in event ([b5b1558](https://github.com/VenusProtocol/isolated-pools/commit/b5b1558ef375adde0892343e4caed0ad18b6a045)) +* lint ([ba43cef](https://github.com/VenusProtocol/isolated-pools/commit/ba43cef02cbf28995d0b7834b365eb1e6b907ac6)) +* lint issues ([2cc0f29](https://github.com/VenusProtocol/isolated-pools/commit/2cc0f29baebc822280a65257b1feae061c4d729e)) +* redeployed HAY reward distributors ([5c62416](https://github.com/VenusProtocol/isolated-pools/commit/5c62416d2fa791be949c7d37b0490ca221a87e9d)) +* revert on approval failures ([6c559f1](https://github.com/VenusProtocol/isolated-pools/commit/6c559f1b31bd3b9ab1e8ff4023353e54308f8210)) +* set the last reward distributor deployed for HAY ([0955403](https://github.com/VenusProtocol/isolated-pools/commit/09554032ca5ed3b04db228d5359a2e4db2fa8fd3)) +* update assetsReserves mapping for every swap ([3427b24](https://github.com/VenusProtocol/isolated-pools/commit/3427b24382f6a59d8c132701afe9c2bd0c62d881)) +* update method signature in access control check ([e4820ff](https://github.com/VenusProtocol/isolated-pools/commit/e4820ff035e06c5d83caa1397b28dd3ca3cc64a5)) +* ven-1817 pve003 ([f603afd](https://github.com/VenusProtocol/isolated-pools/commit/f603afd7071c495971690e39f1bc4d59eb4df964)) + + +### Code Refactoring + +* [RHR-01] make poolsAssetsReserves internal ([9085787](https://github.com/VenusProtocol/isolated-pools/commit/908578705a8ab2cb6058bca205a6af3083895c13)) +* align the gap in reserve helpers ([c47d6c0](https://github.com/VenusProtocol/isolated-pools/commit/c47d6c076b5caac4f544f1c8a499056d5f7f7eca)) + ## [2.0.0-dev.9](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0-dev.8...v2.0.0-dev.9) (2023-09-01) diff --git a/package.json b/package.json index d3ed836a8..926d731ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "2.0.0-dev.9", + "version": "2.0.0", "description": "", "files": [ "artifacts", From 1116c02c253e82cb0483afc47fb1fa104152601e Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Mon, 11 Sep 2023 16:41:33 +0200 Subject: [PATCH 27/39] docs: add audits about RiskFund and Shortfall --- .../061_riskFundShortfall_certik_20230824.pdf | Bin 0 -> 2000005 bytes ..._riskFundShortfall_peckshield_20230825.pdf | Bin 0 -> 386716 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 audits/061_riskFundShortfall_certik_20230824.pdf create mode 100644 audits/062_riskFundShortfall_peckshield_20230825.pdf diff --git a/audits/061_riskFundShortfall_certik_20230824.pdf b/audits/061_riskFundShortfall_certik_20230824.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f1b568bfae8bed2d807337a8d306f9b4cc744e75 GIT binary patch literal 2000005 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%0AKoII~zk#zqX9Qc`eX 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∨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�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

1!WL;+Hm&eP4(kU`6urJRS`=%Olrd>F5GmB+Q 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℞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

p@}<7e4#m=Tg3G86*pGy*mW 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

vL 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

TH+-@z}9o6P^W+A?*+Eyv%JWl<=+%c+)u?9YHd4 zh&3bXgaY(eq}NKbmxdckrLKc;gK`BmK676de@;8543f_EuEnU}g7sKhhr=-(!uWzw zBA|I4(2V4Yo*^AoGUj~j_4ZQ07DWiFS-))>mc;VIjI=YknY*LGV2gB;dHT|Y#3PnkfpC)y}}&pV!LBP2Uei{+b0ND zy`Q+-gPZ&9?d?U|9Okf4?&#D!N?OR4a0!rTPElGZpjI@KcC3R#4LYOtuEmhxv{zp& zIvfs%agc1p<^lX*i7R6WNMx(}LP~Pmz0szn!(74@Ck21gM{kkrs7O{UGdy}fnSu_J_QqH)gRHOO}uNP{Q7N`|ix zq2EIHz(x!-8*ao(rT|Gw-)NIDSpx*%tlxsPQ8#BW>$bsf>~LHPGF&xd7l$%~ofM+A zi%{jEzSrAhNV;L;hCxZYtX8Bk!O&QAyZW9b-}EhpYYV#}kF<(GuWAaD{z)v5B3A&j z5a(NzZ+SVa2M=xrEh-~I=7w8=9HWDg-9u02kdnPIRUNa7LXoT5d!s~(iG9ZAM#H#_ zO78vSqHJ?Nm_rI(5MhK-cPm*(&}++m_#F;MKKe#LHekym(<#sSwDhL8Iar?Ns)t+Kv6S9URP)WdyxMQ0Y* zK7CqA6iC*aBFA1{L0)tT<#0F>AVoG6@@7#mc#+)E`&xE55|G8R8Bc@ZfOE8|IKdd9 z@4eYdjsgrfLkmk4sMzC}RZVTc5lf?R%~=R?EDoj)%)d}(wg}57P;oYE><)@Pq1kPS zbPP5juDtFHHWnT~ek^0>=ah}1U|Kqqqi~RRY#W?l&?|gO32IKM$?GwBf#5o0HH}tORs0s+lsxDp^ z0d+u4P@g@Yth*mx!pmacH+z8z`*hE4$+6$zm<7ZX^E_JExz<2(w%*;{wXZYP_?98Y zXMqu9a0A`8wsh1CU%NN)Ty>rez@ z{3-4_A`V56TIxbLZ{0y+7Q7t6VP_BFgbqiDZCuYWL5xeb&4USc&6-3StR`$y7HGt- zudlIVq9&z$^BfAualkJZ9F7UXh&+Rv#VjNezkLkCZu3*f(fEz+bbe`wbGthJ6k0S5 zbh>K`8X1l!=(_R8KmIXhKCeL)k00*S%3$_p8dt?B=u$ha(Dk4*jo1_D-_E|Rp(GTs zLo!WdemRa_*rfi+)KNY&6(9{GuS+&LH_jq7R@k}hb5sJ!Dl=2&)zCl5$JHRNx!x_< z=0RoyNK3V#c<%%|=NCFO_PwfhIBbG^$XM^j`AjD0NR|Bk6Ng zA2%Duh{-VSd89aUmIh~+dV(EJbBtj%YB|6dG(cSkngZT?@4b#vf`q_1hFn?<-Z;tO z_%LO2FpF?|+UNq7a(m(zRX%Tg04i4R`!!))l*m@t=#mXb*WHNof+ua2rH zo8Zz8u$qp?Bi8b+9Epp7IgWSkb=GkoNB@i8LPz#RJK(KNspNoVA-7tnUU6F@3iPPb z+7R7LcgA7xJ{d}Nk26)JI-4-f4(+Lx_W<79aeC++4?^W%H^IU>sE^@Nf;wndwj?!Y zk;ICs?LuLklx}B~dpC5*KYpc>Lu*v3!&o@Ie_aPmaPsbM;!KsBa)F}D}(*ok> zpxa-j>0{fV&yqT$N_capmc|T<$%%_0Z${4DJ+0ho3+mz2leD0!k5?FiOuG=ho>&L9 zVkYD*1EC{%5sl}xZQ9&_D$sVYXg{ z8PDPufA(QELT$r9KVwBh^)+H@racEIyCMP6jJVVVqvdCbayTqNykFX1l?s7#4aZ>1 z5WlRx8(G-@cD7X1N=-Tuie+7>4k;7{J)Px1y|H5Eu(x?xgL3Q~47cP#A^aY-$#8gE zfuD`9fH8&eQa_7z1RcpR&7kuu9%tSw07I!*cXZ(GfJllJFqth7xL zqd2rX5)dck#slg+-lHQk^=g=G)Q)|7Ah`cV8U;^k($!-zcx)2Pu(`KUaJttVWOBJL zfuWuGCQ6=Omy!fI97Evx`Wg$30f{c71UotDFx3d}ntRvfTRb{J@gNCNf#dNwqOwsW zQhPn}*#ZxzBO!lL&~f1VBphRCp@kts9cowwY4FTc70^qJzO>L$2~etFKwEAo^x!q+ zcb5ROxAd-sIWQnvy#R%z!ZjHMpbGL<#fgAw1KsO{OBO&vOFH`Yu1izU^T$P{4pcUd zCwK=s95op}L>_U}ytRbtMa8j=Sklc}k@;VYyIvmj&9?P4(5t<9fFKXuQN zqjF`8t=JIM&Vh3OtKiuS{T%FgC-O$@$3OmYLC=BE;c#pcOtYmfwU*)iFBA8Mt}BT!-T# zU|sAmyG=((wqH}WDdyQ}aA!(-(t71P95FDZJwdr+^Wdq+T3FT^FnbhKk*eW51`ly$ z95q-m3$UXgjR*7xw5l<+IQ`ylZf=J5Gh}Y-99s=TxeGFr z*M=B`_Z%ML*gV3ptl?x-Rm~i7n|E;AzME#`I5VB~uFJRSKcMgoHyd@}SpeAEF_XR@ zI`^ar$P%MgE$D7H3B<$i^yx~>L-EtQySpngT_JPa?Cfwj+Cx&mji?F|IAGR3tPQtK zGqk~GwPn7QH6rnfZJ=#byvLh`LWD`BhoD$of;h*L2wjFdQQ#HN>Ok*z&Kb8& zIV=Nn6-!LFI%o~B6P9HMT>GzHy{aU-)s)?3A=_dOqjf1{=2~hG`mjL}QX5$E)e^iN zyDE08?w7?(vW6C+GH2&@c>9yNvr9RO>sLt5Fc9xjF^KPz5VeSM!fI@ZM~D_kCrx!Y zj6s4tPb70VxBUT)9YZ^-sD~i;!}#@ zGq|Wxy-Ey+Xf;R8!jNI!+R3JBKq*!o|cFvRY^6Xba8gr_Q< zDjs@S==>JKqorHs=J?x{*Os`UZsr6!!6+h{&an(3 z)XhMsd?HJ(B`FBHEP$*!|9j?xMq0B2!;|LqTgn9W3TG^t|JxwUpVMnV1z928_3BC&~)4*z6zC`ECQ4J-jQ6j* z^R)+a&_JOz<*UY8jgqyN8PCy&&1y@=W}xh4)}>%Ddu?tO#}as<$y?eY1(IxsJlMKj z9=ak^AC7)e;usW6z6qhU8DGSekedQKwy7dOTPRhYKY!l4F1rA8NvM|(2aA~v%T}x} z)+<_2hcW}!#3ShT_ExbG3td3CkBb>6oghPq+{5-#F(__pB{5@uIUalN5HB6f-o0)8 z4#)OTBsl_I9SYV;u2hB~FYOW==!RU!y0TAu|wL1fw3FK6N!G3EBzZCXTg0R`=A^8 zYJ+Jnbk`6Y2Kz)k{lx96EUhc4j7M1%=mAK@QEKa$1?9ttx4qXVlq!u^nLe2vT|hE? z`_@sp(@8raj1CzKY{$LofWtDj*Jh-An1Nzi88J`@b;e++ea_LznA=pqbZ2lV*f~3C z*#CWbEQL3$u_Gb_1MzkpmpcivFo@`XT}(|WFDXeoxS6C6vkqxn#YIeOjx8bNeeJmQ z*MK#{a@f_DHQrgE!Z$ZJHiZMZAGbGwcLfGbSX;9fA= z(8FoyA^ND{41F*Rfws)LlJxKLz!5)H5BRa5*Zy^y!?D%`*xS1p9&C-*0OKK0}WH6{kqW<1-hA$kzJ2)4ivGg z>=W36xfl1Y$e)2~kO}APqRxyWq>q;0j%^PzvK!kPOaa>y)+w3pde=n{OciXkRKvQv zO`1ZEFYbt-+ey9SWkmyq8IVS&a^T^&ewgU9XbMPf#?;4*r+KY-LodrDhP7eh^Z`k+vd z4tJ@?Ie_&RxEw&JRmlM6=g9whg9i<}t8$U78{!7||^#>d)vs z9BFfCZ*%NpQi8eyB=5~>1!LUQaj6c2z!r%EGN#0cuEoPa9Dp}$-OZ6vn1nohS)Prk zoA`gK3!#m)i)ZGOCr@%>0~tORx_?N@wzE5Id|4l6>nn0zMj=JW-X&0O#Cz=_04-uy zH?3$X$u{$EC%1iH=5Sa*Rr@XdZSu>(hD)t-2$~d|U^0=+qD>Q-du19ucT5`_runb6?j1HvY@p!x_Q1NWFA@hsOfz0cqOW)PzMMfZQ*q+^E z4Z?g(dz&h2Ajx8^h3b=5h*{cu*To#zIr(m`Wg!M1``$s6qJxIl@j%qK^5M;zsY$pi zFb(clVdj2Y#@t;#_1n6-3tAwkwC_J@JMOmOH}T^ti0my{*C`5=B% zx&^W~HWiwQpq;MoE;77ffOKJf3@oDihvEz<7i2jR#1gfqrad$WX;fy!mIA%{koHVQ zwr*w|9lap;8rE_>h_keNU``PFxaL?CNtIBlR-#4Z@H#dFeSQX&pB6}cCC%Kp-RRJP z{3`0Z9x5kW3&O|sC0 zgmQy!(=?N+17~>iUN!Pv*qQQQ5xOv)btQUq4^ar$TkNU)(=$PQUDO*ox;N*V3DuC} z-e!#ar9u%e1#fU@tL&v;4Jv9JrocFBg9l73XYyOtt60^QOWm?k$&fsmoJ&vwse+c; z3%I|uza!Wo=qh93bT%T?^Yh6Gy9%g}5ng0l@Lh2@wg>S>XdiM8`6fOLZ3JCNX5L^29NJnTWFB(flH>8X@yaNYxY)7T~e>pmwtULA-$Jr=V$C5 z{`?TM{{%wA2Z)$9mbY$sjbrC za9Ds`mets>#7EsSRqvj!(sCdn)!na|b_m`e>uft=%&Cq!9I}GJXu2IglNGiUq#BjX z@(#x=jLiQDcpij4U@e<~O;d@ZF>t`d!Z{v~PR-W~kPK}Wqk_gn60Pdq$j5chIvmBp z0AAnwwgex|i@=+dN}Wd6g6`fCjv5dX#|B)^B;7!%Y`;}8Xj(b}^*}W%EaXWMavLVr z>E)8)*e!m1!tL#?or$+qGV@;OwTX~Q-RubF_^CSjLi9Z~8~l1uL%=Q%AzAfB6BOsQ zGd0^86`NTIn$t4OdAE@5c$4gZdjl_4D!BkT95q0zh{4HnOJ*$q%1uV~hR?X#0_2~3a&^sb0w z3@{B7g^XI&XO42hS~6eDK+n@I(Kv=NwAHi`?4cIg-YE|1B`KW^o*BtYymLR*>+5TZ zAoT!|>$~suS-rQ@C+FtoCVv7mzVFgikD;NYQkYLA&0k1hBKK%#3yeLiLK3YaeU5b} z_Tijzs4d^#-nLO+_e{*l?32A~;m8H%Fyywup$wA|J2Q_%z*OLwc?JoTKvjG=N2ZXP zdnbEP*kl(74r`#Tn3Q5Uo@sP30&@J)!w6Qja0^#lPEtkm26l6tF%7C2htsLSp!{co zFz$3M-;0sLSU1jjM;btz)5DPorj5IZraMGtro7Du-WGH)U?Gq>>kXk85t_yDY8{a# zo{iJ|F+MRZmcCg|qLB)BJ;ea=jXEbEOfBrQnH#RSiEb&kOV~4wkI!-`W-4XLde8{z zhP5JK@~MH0y6e$KF&kI?6E{&)P2fEUM3bpn#UK?xJx=@D7_{0BhfPTKRkd0rWc4|x z7_4iu4EX}D4c@%dH))@ygAIVjpJyjnTQcj;GoC#guP`9YVM zj9{1Jw%k+HHZqVf;cy!9v+GDa2k6~&JRaAZLFj7r`0-;-Eoq=`@zQjeGqq^e+a4Pj z`lO39Dj5r{-Sw&u4yU&biUiJIHtfRvg1`Z*NgaUBpv&gpM)W zJHM|1dH@p}ZSS%#2%A%FvOXb^UgPJ0$t?c8jKy0oZNeD^p~1WCSFc`KGb}rH2+T$( zfsoiaBnFPdJy9Dvb42S(cZh_n(R(D4r7v*}sY}~bChZbx$XlUO8y~Zwjq8lG9zriO zbW7>+ZdS41Fi6nqCc#n&6A?Nc*{)!dFzRqpbh*8@^dc4#^=8cT*!0D>q`e}_u%Ktp zp4prOcA%btG$0IWTk8%w_GEHXH*ljx4aMBF@?AX0E82ynO1BEJgAJ`kI~YG20YKnt=(avyswPyw&h_$1KG7V^a=O2WZS^E*;X$%Y{x9^bXppD%-{Rtq6Gi z#9868u|2{|6N55p0@Tnai8VmLZdkN#45Ws@&!IK*FcsZa1p?iNZf=f?*|MvCm*{(86}DKdNIA1wYspk?Ho4IxB0ny zgt`Z_XxoBaor%T{!lQw%1X8SE4(E(@W?V){&NKRm%py$EvCmj_$5v5lkD&3^&SqK< zI7pIw-iWN@Ax@_@ur1ITItEkcFlNiv^TteuGHei}d)n$XjiUy(t*h?`5XCkx@^}ya z>eZ`pHCXjF=h!?7^42OIXW#~)a57<*)d@kCc&X{kICKGp5>iA*4O1cHXjx2p#ml=k z5|Sph#)`UF(MPw3FvqU?S}LDGF;wr>>a@YVxGb39!=~2Z=nHbu4|*M01lUQ-@_jj0 zLcDbLIsF&`NAmC@#}=wjB>vrlq1BNOC~u_fGtSzF`OHLPy(_X!@Qg`mY>+qALNp%@ zcco;tV?SWve|qLHQC(*64t;x8QmG55Ht77%@qN+aL~h_iG2^7|8+09?=qjP5F5M8i zzMox^Y+xzNcAMoNx|FmGOv8K8OB}mB@3xO0KgQHzn7nSpN&AdNt)qi;IQ9&NWAH{Y z|6np`m^@X2ZNvtS1*V3905{?_G&+jh)HrqpxinYb4>mxU3c1Z2>4DHV=N*G48AoRQ{-850d@2RNa~ZTY$6BJGKE& z=d>$4dGdsQcWM$FQoI_cn2=P+Z7i;#6A?~r4c>Stk(wbBwKX@Ut{9YU36*F3_->;Q zXrG}AkZyi5Ookpr#j95pp$$ZLk4Cd|n>)Cbcf=B8D!F)cWL!DUgrSF(F0rpzvD~8W za5yFib-8ix>-VX06anwGF$Z?;00YGvXPH6OZw07vp~*WR_p*SZ)$By<(1AQ@Irbb# z2}aVX-7x6uvgfGSN?@Q0FRYuHd6~)$Z?tSAR3oJCa7C*NFq2>0Loo!Qw9$#I{L~?+ zIVMtLZ$^2${fJJobF4gqiS3=qc}eNE(m+HzEhQBn%nUvA+cbw`P)M#lgQ^R!6<)o1 zRn>2*o})YSN;FP0y#`Frjji0cI>(LMcqMB?ys4`i78s##WLAh;;#6G)Q7XpPF$?kl z>Od90abfwWb?G7jK1G7*utA^#19{4+69+hk20gT~?)v7fz)CTdL98Y61rAnjCh=EJ z>X6WRX2Q+QTIUtKw}A;%QfwXiw466l~CHWVb^<#&QG*MLoj*s8Y)Po6xX zFs!sC$q_rVd|rK`v?2>rvR&*UpF5Stp#>Voy|#Jw@bL1ndv`IU2xHg1CR>8<>`Oq; zkfSUoiHz)|YPm|5OS;ymog`_`$J*J6nEW)0^Qq^J9iX>+`@x;rJ@NC z7g$F+iNWcC5)9sMuLK&7=6CU%8U^%#T6vJ6wN`Pj!MPMtAw4?b(sK3#I^B)C^j1Qc zAuSwF9Bsht-aGV8ff(d$hh|$zjeq?3G5R)BZiGa{MaBq?-2+WD##e4(bRp-v0z-i? zSNA3d92)>{-qllA%=J04Lc;NU1+@f?>ZOt;Ibz5a+a4~n6kxjQmT{V8A!^dy-Cggx z3<+9p)s*IDfgNop7aZ-un40_vBf`1a)eNK@s@>R%EB7O%JTx2*%iwL1@u^OiW2{QQ z)42#?Kxpr}ICcT<+Bq&Oay_KhG*}1WBi#e!Y?b5uZy}q!LxGklCnUqsn}+$Dpr24J zZ~4*?j~_qgxx1dG#Po%g3U{Qz>*?*8R+>S4&fm06*~3J5YC{3El=Op))`YlguR_xn zq27^W{Ra}}_V#u*>)(33_uhMJsO z>In9wY4YBX%t~i!ljvR2yf1x?*NbZioP{WUEUAvRACJd^fjo{4gMty7x$jL5M_IIY zn%xG32WFH=0TT5vUyrT?=oq|!&M{-=(7GN@`YP&xxr(3aI)9;qn=j@XDbEsTeSC6aP1X=b6ZEdjj({~tB0ihcNg>Uw!Rk2@5ZBFomm!j7>|A%kK3m(yWrw(f zJTL<-dDIqC)MsgXkfh7VymdIX2duA~n;WR;esLUwXG!lFM;C;Nv$uLFwvtvojH{(R zL49GN&O1p^8+3uW4KOAG=h;y%${h{x`0-;hfmA(u40Hq@2y}GMH>Y@-?~qla(tQd; zKiJRvyt1KP&QBSQK`jn?wWm7B(Iw~&d)IWY753XU;+B0Nm?(XiINlw}-Ydfoy1@B(> zNp6#$;AyvzuB&t)4YTCruO@nr7pa)UaocxBLRIs-Zcw#T(12BA&w){7tpTtoc54Fd zf-VHnj00WFi=xBX+P(ImHF$3e=p=mRkuCG_gY9US5aWh!IqCt5P~X{$IhjenJP=4i zqC0KT$&H7#Aq0*f%;allqomnH(UUkqTtw&;g2(N|>4Pq6D8Gx|m@}`?G!kBgAJQWW z&B-yRV8YX}f2n$tu*5V-HB-;D=qQCyZs^vj+`K5nPWbp(@^%f}ccKU&L-t@wDh_TI z`N{x=xjSF22l^axHQ#f1C78z$ud}20bpf62)%(b$k3%jUk4MHj>E5^vkO|@T1jSC5 zX&vI7zS{BWa9TdyPv}+AAftq3Pz~GpBDIOVk#g)aCp+X1^b>13WM;^)F1S+U@bl-- zXTN}&Nc3f6lD$l`m{dC)W$e!K`Poj!muLCV#7clwGppkAdJ8Ywd@RhaKqendC*6dU zX`}XO->Oa+#%R0mgkw-hqF$#PwTXPk4{K2K_DDbI4&XVA9HWCyHM$V0d_Q@T^!hGY z2{J(KL$_!)$C06z*?iB7+CG?$=XgBsWbKoLq#nEeCh_Ei;`jSBXwc=Rnc_q<9fVR^ z9AP=+WdGr*{L&IK&0@k^6*rA(pwE`T$KT9xATy~k1jVJbayT3lKpFe&v(Luj)ps~1 zU=DD7d;*U~gb*#mq1z$4Z10(3Lv8i)LF@8lQDE zN&s@~cs#1Nay+PRnpn5iI9ZJgdYD6uG;SlbVr*5;&h2oF4#?Q2PoH{7W+@ShT@OlK zC4tPq4V1t0xVCZOw9>tRCBv{dD5W0yWER6oHq0fO&9^$K!h>@!+mw)UxNWKdLMF*d z8Lk}@&{{GU1$1}N&Vx?7XxE@ym)dqwg!vqG*!DfRIHxtf1GR8fh>-#W3ag=#GxsLG*G@^u`j|=H38}g62WBg)ryRZRZfqF;ko#jv}B(-<3}MokV}H}tVC6RS2_;SM6)+TD{WH{(fJJ*{=?le_3^e5{aNYYOxx7W z%}w!H%A25$d?^D#{IP+ZyBfBKu^#6pouBG)moVqW%gOT5duM7 z`Ibz~0z{36LgxN}7i7OttY8bPnh!UP-M~q=GF>j8n zJEV;+FwUaD!}t4rg6Gi+hYoHM=`o|(p+X?-SZ$?)D5xhfACiNm)?kc;5tY_E8tim= zmg)Pf-vyLlVa%{#I{Pe)=@Hrdn6@fp8|7zh(eRjZ{6C|(FJc5u;|4>}8vJ5ZFehKg9Yw^uO0a@D-1mg$CyzK*V#CojhjjJ`lZ4m-Ylkt5#pvG7;Ob=jZ2KUXvJa@%CIBZ8X^$Z=bL* zO!gXfCzUa9_=WsD`T4&*;Rv&K!o3M|0mI7#8a!jLU@%!;14A>dudjbp*fSfj*$L5iS`ZHg&gcztdK(CzE=u}Yz z32PsDIIN1k>XEfn?2+81pB~0NlFG8xK4gh_AFQ$)0%hCY7bj z@6oIs8IWjCqUN7oj)lI!S?%^`#aN7K9nnonAk7&uybE4CpP%mZy<~?MA z4mCgZSTse61G5PPAq-q;8eNHolM5 zgSwd5%&ahguz9jcy^9n^jpJIix)wVKS~DWEGi8$pRbY}@;T$2pY{{z|#RTKRgc8C#=fy6V8d!izPC|>xEb}|efK?9^Vy8mL(F0uJ}c@XB{nXFZQ ze_+~##lyo8X-Koebw}02SZ6umWF2|29ojwFWGf@0Xo?qdkUPv2xG{@vD*NZ3Uv z1F2C@wz3Fd9)vWX`Glyy^17}_PHT_CVUGW4MT&aI>{F4PQx2vLSn|k8&5}keQRZGI zQ`}89G8vCKSmg?+juNO&^(QO4ymoyvF-A_N(G>o_TD3g4>`OSX9&(-fBRlCRqvSmC zn1RUFM43k)&XwXM&=h_8bL#Ps@hXgHjlhYAym+O7MM$d zTwo66(RI1gvO2iy4KV+%c5ze!?9MB6NQ}okYCM;UgM(GBC?a_Kd?v@U!UGCXbk%9q z!qi(M*CSIj28i)e5fy=Xak9yl4Wl|tGIioP zz4J>IBDaLo|5>w39sMbiYZkZDXbu0bw-A&Laty>I9z)_FR+^sNhVJvob@ojhC4spo z4z7>TJXDb`(2@bOxdsqh7)-bl;iujWGG)B!;2MyvhcOX=tA;C%z)hHJ~nk zk`X`I{eGXkU9-wyE?pR7ckm2y1+`GJ;L= zDXWT75wdZtq23n83|CUc(5g7$VOx-jvuk%Tb8&%Idlb7?QHi27v_=|ZLg#dvC3Av~ zH~$cY=hM^EtZPiMXo{S7^2Uq9+eMkyDHfWuM(*rLuCa=D7Ox#3D;HRXtBr&biFwvu zAq}{E%0KRNLc}&$TZpm-xarx3gJE^#4TP&S#+r{7Qo>-Ngk@c0_OT2dsmfSoK4_>j zXqu+W+kU^FFIDoQp=rwn4cj<9jS08HvZWbV;hG;#$5=?--Q6wuUfNtO`9@_t?8_SW zRq=rqf+1y+LnqP9vd7$3W@S}sTg66?uc{r!yJ+L2s_k}*)q30F4MjM{Sj(N3nh?EZ zOZKs1)}qSTdMU@yB|G$b4k#8NY@j1&32ewVg~5VK2r|P3X=5AWRUomQ%MZk-_)yQvc;t}N zg*Spt@~R^kov+5I;8;~*snVEzEVl+Q1Gbc@wZUl=3u+yHMWXN(g?Pp-ACv~YY_;c1 zF^+NCf(~QU!Zn4)L-mwu?6UxovOxWhYAhAPqirU!znYI((^h5=oeBxzh;>TdY&N+e zUImO~UiDGGZ9vXMwxblj|xg3Tr0j zreG4Kfhv9_c;K`qF=C;LPBcgBn!AU}_Ptsst^r!bd^<3$0EyuR4{UN1Fbk+DNHsS% zHwlub972(%U*giH_AMbjt3?SQK9$W3S$ayWQUaWPs55DP(LwX4w0U+=z$i>-9W@l~ zHzt(csoWlv5#PirR$&;F3TXoz?eYI56{mWlN-`@6orgT`_j}IW<69;zaM0@JYj4y| zO=9%OQGyEgNzzs+bR3?1ivf*cs(9~CFnP`QaM}0C?o6k|!@Za^t%Ye7GodSusY@?# znKY`5DiN=TX+ApL_(UTLLh8IIMtd%O-4<4M*APEO&EK5LWXL(w*k#&N z#(3Q7l5IvzP0APYM>5jZi9nqcN(dqF&&@?ZxCG?%i7wQ zFe;HoWp5G)0An=#6H@-cPokS@^#tM45HVGw1Xl#4vi*L~qug?*#ZCD`&8&zydd5P) ztIOP(O@KSOY2oQ=#5}SgO@V+RB3DoXv58GfIX&x3TNW`eFKguT@-laFx(w2#u!4}0 zG~Hu7qBmQt#5!@S+Cw6773Ir@ismV(Wg2qZh}&}Vg!2AC6`36bV}|Sbi4B1EIezDw z?LnimHwkr97`F?wa8OnbRsjs$RP08fq9{WVx2%ydSd=W#E0$KNZLhU$#73^bAjuHa zo0%xn)}9GE!^KKWVtdYaMpAaLniv#`YZ**Cq5?IyiZTc_6B5M2u)yhf8Mw)tI~B?_ ztjDgn1bD#l^YgR171shf$iu?}W5Vbps7wymFB%6vBaGI&W}z+(naUG?kX}N^Qq5~#uqcbER>Rsg-MPSSj4Cb}SAz~&} zl6-Nh{e1?w+xgvFpr<}4agE|FS*&{En}824CXv$ zzOc^?9ElhnL{6q+0Jgk~oO!^_!mloB!m1j2Lu7Z=L50dnaKcHD=P%DB5K3G@wEr?C z^BOUC4JK@ps31OertQD;^K%)xCvOa9tfy(8oRPx24B8>85^biI^EzvXzVn5*3dMv~ z1|hu64q}G8$r#}$Z!&1Vp(@`=5dHbj+(8!?1AV;M4zAP)q}j*E$Lt~3uzcI^_W^l> zVWyJLvf)^<%(e&z`A(4{YYE}v1KR=O7ZW*^mTdzTUEY5cb2dy!@4S8aVqA`9xD z1)L{^){8VurH()&5#8xb{etR_sS=FmV0d|YdRlorA8C^)+X*G2xf{c~!(28~-BC9+ zVPne+3W^iAMiEhzjL>0+@jr8?WfmZ`XIFS)X^+_lC7eaeEvo|^Y{$bhJtq`X7l2~w z;{i4AuLb%RHK`Ib_w<|0AQ9`VWc5h=v?W$v_PZ`FE(S%VkR5!d@{oq3gF+eQ!U2rf%eX$p^5`icSb|{cw}o;Pdt1#kCKPGBo&F29a`$1q7PSJxyHaq z3o(hOA+*$D%Y^HfF{eS9rtj0HO(_K0w&gu&Z@1fFSkQgsEXZlvKQ+K_J(#gu%b7{1 zvTdeG66Az(vNjXRXQ+uoT;%O6((&_nIp=W)kf7zrZ-MJ&o;8qMdX($R*IFpaloqTY z01q^o>Rg8APasvsfHszQJjcwkm)`YdJP}6ljMYrd-HaB#5FFtVT9mbefv6lSbfjcxSSR+TySux&M^qlJ9r+dp9Io0_ zW^y3CL(s}KQ1hh4?1D!Erd}vn8zWliECWG5|UAt7JzTMajZYOGwj5Y1V|v>VC0qOH1Rt0S0~WK#+J#9y#-F zjsiSCFzqut4YevXEyj97w--i!L#UdGu!?hP%tdP%ybu zp|l33X3Q5D_KRI+W;AAA3=tZ~m`}_x-zmky*j!oOD{VFJprNfjBU<>1G8J@AoZEfC zbb*}pMS@rwV+A+T+z5%E_CV4En}5bfeSCbJRyQSvG_&qBH4tdAC=s`)_~E7j_Iyeb zS&M0mCNlJdh{mAJ7)Gr*?B{8e(uUScgUb!YTxJ$KVO?BYFg{GlJ}-1DNcJq)Znuzm zAbQnhK2aSQB2dVfSoQq+G0?LhqhQ9cCnb+swa~`YuM`fKPBc@=otCCZ7=#y&)=uBR zpQD5P$hkIH3C53FxGNx)@mQh~wq+rfP**nJjAn*?nCTTOf$Q;~BSN!I4tg1?b#4P} z<{EFAWLFevp6a;0j7*h&R2*t>^08>v;+-!jlXS5L0keQ38Z0AnJFeDsnt0xys$jAdsdC(YG?L2Evk-8}` z6=+N7!eNsntRhSBy^U}7=p&2~(NREg8=WJ6q-BU{wN*|;vH;6S0?DsHTVir{4Y<{@ahVtO}^Kr4|C=j*LB#GPF96+2QilG-;<%^1bYtPwCoPqG=LGytaT z#{)x8=TVji@-6yoAu*#ceMsn@+-a!^^s+)?m{cldaaGG1GyA%=aLmB(X-#gD%?p~l z)H}bh&o(wiN<5`3Z%1pCMU5{F^g8)DB1#YPIBP)B4ibIK*WCuq-6$6NvZ)4sJmM7y zN|=1pV3gzA1If8)X%Jf;F4!S^G;=7}NVrir;TS6-N2T$H(L$=*?e&4WSS&B5DlGeU z3^LAh?Hdjiz6>>X;T1yH-8Kd;^xVQdYLzfD7eH>$J{Jt){ej%6m>mohj1Ze#JF-|# z-X&+KocjaGWlmk9jujKK-EK$rSuw;N3xofHa(G8p9K{eG_-CCSKXO=$BO#WRL!(t1n=BR}`zOJ0xUg+&ArrKNRo z8tiW6EXT4VDwm(5&#ha702Vn=(`&x-qm*+q9>mln4E1)T8Rr}eCHC&}V~p^8;pF}z znx#T)1ExZjAq&Jta?*inS^py^ytwI$RWNZHVw?0+5VIHYrJB! z1bA43D)2M1KqP#|j%!IvJmK1n=LR+~0xN=!X^OHEM$QGYnr_B3MUS9LgR!>eI5sx{ zMmQ-XF_A!y#X@hl+qF9R%2x8vVh&`i8lHeQ#-Sz`NG+Or+oLO0%_AKQO90h0l|Few zt6H9wIrM40x`K}fMx?6E6 zXt<(E@3|4n{N&(fs3R;h$Al&>4eF*)GP-;oN;$n%8n#9)C<;1&=(IQ?D9q~IALPu4 z$H&LqX_*Vui?~`xYTc{j%&GpwM_OE#BDhq`*}k+G=v|kOtq3Ki!&9U&02UPOJfW z-ifqNJwsNRgxUq9$q})6?g8Zb`kF6VSXyT6>&VG&#^K2h*Nik7$}%YoGPTMDo!}PUm_UWn@V-FxG71C@ zk`rRW?OX_tG~+3}&5-u2kn004zh=xhgL~1lazzW| zst5lMX!2=@f@_kq$zTf_5zz-7*%o`9NTI4;t`}M>Eg8{wZg_g&&mrd&tON>RB}mtK zVVw4cPeM_8;ko3?4}GQqMuB@e?~b1S$tD>*a7tb3W(8$?ejs;3hQX$lI~CPKn|v&V zYP5eYkdaOniqbHm2~YOPl6}AhBAMGTy!_8#{3x;QN!Ct_ImDPT8Ogv{RGorrjDy=u zP||>~t?Ff^DA2o0>nutk(EVBMI+Ec&8YXd7{3fv7Zh1CtnFEycj$&13N{wbSIje|&t5)J-{S%3Pb| z8jI-OIH(*X%`MIBC~;HD;Z2c zyXRE!kQ%x#X$L72F`L=%_qo#&3*(t%=qSOMSsV6HAf?N&U){F8qO1Xot71+$`4ESP zk3U{nPYNJ%x`#cMQi+GbHomCG9NA`*Al~CjDjqSpPn8ToP90h@vX=N>m9WgI6jYp) z;T#QPXkvK6MH>PPhkBLAltP&GnAi9;Fe3eUL1lbOqZJx)Pv#gek2Y7RHv)}K>xL6iAQKpexttdJaV+jVy;#Q2d)PU`GO9#V^VSFsa zR-swlGELpwxz@UPcPM;JRhT}sahmYlRg}!iN3Fs^9ZCGv+-X@0;+ay2Zi?siK>Dqs zs}?)P%F&YB3mFv`z3wBa!oFH@1VHf zvQ4wh;$?-PeM(zR+cBZ1BuKUv!;Kh-lH-8MfDbXXM%~5SOzTUV1*Bh0ZL6D_seVEF zC)|jUZd-ND@^GIe&FY%m3sa`${y+(4v~9x(v7G(WMu6%@Ka4-JI8_b#c(9s){Mo>c zq_PYc)pxsH@>*NgN@=#5BDO&$Ol!1~fHdV;UFiHf2UNnu>-}g{xlEXD`VEy3P%#F~ z<`7^?n8(l0&u1+$#zLviW(KmQh+7FMH+>8a`>lEW7!v}9OJ zWrw#+D?FQypH+oR4zCmB^4%m)C>MBqv-5jB)h*{9LKZ4yD0^R%=YWGA&dQP`$6S zxe^H@;8D4hw$Pr$`4OwdtE(&gUx%{AKv7dfS%c}tgqWI*0)sN4J98tlgnj&3NsiaV zRW_(yGo0+%M`?j)yHB1frC}JYXqk6mX|rbiKZ<%#-Z`vs2{2O~Aw7(0uD)sYVxCNw zJzNP@I@*>xBm}-|7&H%E7!HLtu4q3PuJe|j>}dS>@uPv+99ejHc;Mby@*;~-acW9mFG1WLmUepq9_LkB5J$0B2? zx+#r;isF`JPMhoNYtFfkkB>TPCBQv3^tee*H!G6{;_I4lw{DCgF=K&nq6~{D9RJ50 z9Z3J6A3uJKRJSs|P~KzZO(Uq5PNtwQ{K%H9C>_k>McNjARs}$!Capv2Uzawg~= zo-C-);}!E@;k7eHV&rK%q?sMVS`hVV8c2SXQ(#{uncNh~SO4S&V&pgC1elnWLYO9c)qp6VX zJdisrwL*{Vhlhvx0*h4#M~}SvWMy)AU`@&EcPHHYL-*9ROo3qV9O;qQJeXp{Go@h% zoQ6^3`3Y&v&S5+aH!UpUI6L6~4QI1qC^VM55XfkUnV{K-0pc#7oEGM8yz*xZ;tCzU zhKH(*c@at}ve;>B;nN}xU0jIOR=fo}cNLRQ3!N50qQ7Fh3e-f8<(3(*^7kJG3mfGU&uy=3W&0VkL53UK?HJbEid75|QJrry6O8diFs`Mgq!lE}&6U$@311iw6a! zDSo;2Gsf#yY=n|EOJY{>^z@YWgrX3Cx(4O~b48FlErXF07^f8-YxignfnQG-9fOZ^1Qjt7?Q_xnP0EMk&WvONqFS!}>?qzaSicDv1;kRG@S z(=d06vMS0yN>#zIOz%8hM|3bxSxVDxnHz#>#S8HRGFwqPNrluNw+fAFLUSF8%CzAx zQ(BIJp{Lb~X$+=*FK^e7b9@@mgwF@JKhz_y1a#Ob0dxcr+q6a+#;j;vs4B`z;MV-p z)04_PC6mR?im?UCU(_RoG<-@EQD|#Nbna`9X$4oVqbn7LMa)w-@QhqsTx1_qd2TF5 z`0Op&JWV5eVoF8}Cp&1XRP5{cnH`F4#hN53Q$d5h$HzwvC#WPa=7>fmFJdD2n}lzl{Dw{E3q7k(9j95IVcIjb5$|_+FW3T~!+WiSm4Q z#mH*e?RIQJZ8-l<0+t>;RAmj#QibHIkpP~RN zQo-_PomUF&OWAYF9JFhxQy%4zI~B_65ZjwFHw4jtX?s)k%u)_0Nv=AVS)1^6xyD|e z4mo$r+3j{K**jJi0R4rA(0K(aCIbz-je)oPsG-Xs_CIBc>%}tkWDTVa%=55xftC!U zP5SRAcOo-(%?g!-42+4^Sk6Qy;pWPe5YStt=axBi^Axj^_lb};*`w6aPgx#rq?Wn3 z7TX*36Q2r9B@0h*@nbKp9CL762hqF68*V`c80z*Y+aEJE(dB0@9-*SPl#0?4;_Zvx zUFL!!0OXU0hX);zl!Yn5y*e+{ERnP)n5UMcX_in0jJmHQKnY+4Ar)HeHb=3m+FB4t z8>|IZJ_ag^4ThKfe!u(x2uT=I;j~?nv;2e)TntP`z0nI%RwI`Wcs{rFfBg6{zMvSS zWsusRz8gP>ocPSQ%w!(M*?}khEvBTZ#n`w^&{G&1qF9-2VVa3s)c`ztAa^PTBU@CJ z9^>vLd#F!ZK2Xldm<(kB#xyolvy?WBV@~{bVCAQl)GPmYKt{NIIr$PvDGK!5V$Hfr zhCaw+bm1?za!AwXB`Ud~70}N~kM=-=rvqBDQMD!f;+BI7V78!?eOf-V53C$Xf-q$E}ipGkMhrMIqY9!UaHPkZm*bt)NGoNLm3IADWVzNhNKM_5}0MRqYYYq+s+!3hh}1<-S77a z_oBs0Y`QEf-x!yWuajcUez-g@S@Xl?7>1)_H9z9XvO;S;jQpqrj@|gEr}&GfykYTbg1cK zrQ}XaI5rzIV(RjZ!s>qQiURX3pqFfC)-R?^bMov5LE?NB%M zf_3)}Im=^j1fBW{W-c9zII6ps6@bp=DJ;j5qGj<9dR5$3B z+uK{pErXKHV2@a_4ou)M%G?)Ilz8+wV-s4QXbm%L_^LW}46>aUSu(tSvF&CV zmr#SbY^Uk{fds@i9#J({dOn?#^8>k4u~HaSo@dSHZBckTR#*=Y54y<84(dW8B-f~( zQY-7J;KGV?rFKk33BzMn1|9NPJ{SZTx4FQeOx$=y+KQDS(HWK_%PM?shvW9*a$(4_bVo>TBFVQ^tVi%2-ue^~&5}4F7Rp z$(Leqiyx4=kVgvRy92j%!U-sIGld}ivo1+!p+NzocBMp(P~BR>s*~Y-tB#d~lB9;M zfmI3eQu4UugXQ0b(Sq0>XIv6;VU=syLW7NB&rctZ9`;lksFCyY^D#po?u|d>u?jE{ z?e}|(1EqQ2&~+Cy@4BlvS*^vFVg^#KG0-CYMA{p*xCm-s1+*j(IYzbw+&=Vt_J@au zq3W!15Tm9AECZ9*K0L{^0b`XkB$!x@4XiQ5!bHtzP0%+N(`>LW)T`b!;as!YfR-zX z2LdUsQlo|TFxNW`D7O`*ZRl!RvQ3&YAKUGgXVliH;SpEghlhujTCdEZ(?*GbfK+2G zLyCBOeC%DDPi1J0l|sB802hn1QjIMTBR>}i#qR2g!TG`#cZHzmG}+|pXc!inQH)H2 zc-ZN&QwcB{M($K(L*kiZh|@l$^g6EaI`tHCp({^8D`ZE^yiH?QO12SQKg1+i-(C9~TA%%QH~Y zbW@zxK`vVtNkCe^!|D~;=TS|?*3n`xh#W(^=T6I57|F2eaYGHs6h-L;<2Ix?YL=3f zLSkhXZ`QsZARZLH$yhRS9>mkrQ|`1lkfqJfQp2tLVE9}H4$7StMOhk5b}Ae9GX89) zhlht;ZiaMn#Pkuqj81v$Yz)Xdr+~U9uelj-#?J$SlY`mP>ytFFSIh0iTy0ETZflpo z#Tu~cj9@`jqtS~Tlc7VU5(6Ept83>|LC1*F3mlb z;?pD^4fDb20Hs%EBDdS^e!oZBs%!Zo{Wh?fs8j^kDXX2bYXmcUvOP0*7BI+UF?>Bc zu>5;#LC)S7R1>~-C#RVYnM9}6GJycjV`hPn8#7nLk-}0;_70t6hs>a z>Ag%p{Yju~uS)oL#{nNLv(janqDYvdW+rGlOg%q8XSBha`@Gj>;2~}uHI9h51+M*j zF?XzzH%HJ@co;`BU8ZCj6Ehgips`FTic&J>xn_-pdm0HHgi$!{t=TILs9qOX`?Fh> z>Hki&`>zn~`$a*61XUHTnY{j?<}6V4;9z=xn_^oD2HVLA*lxFv2lo5DYL*H|%#y2i z^j4hETme;F-5^QTG?uj4he1UdM48s4d6DDWO4cnb4_8u!56%qSl-=EfK~V}fgeHYo zsG^u)6oRY;`9FNNLit==T!_0(b$t*C#^Ba~qpKWtkShV#*Vh>}56u|QqXv1%LOF-H zVVDvzvg)!`VvrM`tC0FigPNa*hlc`pYS4M5a*@K^$r*sDvDXdg2|<%MKR-vKO`dDs zAJBP0Nuc)Q+a^aW%;T3N%R3A3KtuX2#lL#YAhS+1T3r@c>QROSpN;+~pUYPvLfVqCzRt>Wn8%-`?I9 zSj7R%bE0#nr7Y+Gp4=(K+Bwa9B};f=Wic3=F?T9f1OrpsX7d5qh41d}mXyuV@wv?r zzf-_W4UG_0P7CDL|B{6)Edf=m8mh$*%}jQaPK*Fq7F^fY*JyH(wHj!3bqTrx7u}V{ z@G)UVo}Zs}6Dm8@l3`jwr8LmB2|7qKd07ME0M&*rv7%t+kfkAhYiuiJ0mk7DJZF8lU|!C17g9bN5ODT0A(wf2XlA;x&+xSybT zPDXd`&-?e#n6hsFZSV{}bZikG{xZm%epP!favPqM9=&!wId8uB7 z9u-q*mXPK&3+hFF&fPl12$9BMb$r zZ0-VQUuBeo8Aq$J^>QQ(?tyh*@^sno`b)e^^2VfXDd-Ja3ybvO;XxecE<-~x20>ZXk4qY)}f zB#wj=B(~u0`Z9`e}8{5=o80KS}H;$Aj&<+ zz>)EJDuPBnJR2o+wEf1bmBJHhKCVd8_=!Lx$2rj2SJTuvTlmI z1{w9zJY^%{M$tc`ip!MZRss)AKrK|g_GApe>Qsdk9@zbJr)3(rD9a)zH*<2OqKu?K z&(M)D2pf8L;Y&y!kj;`W(4bn(Ageo&l+J5)rMVZh7DgCrdzn)#X27d9#z~tRjU)?) zQtpJM%Ajr4sh81xB9CCELa&Ww4ys9PimF?3E`~@!X_b!tb#ow1J0$itX;#)cW(s-B zp(UH!x{x8RjlJN!5!hrf%zkVlw+xyIC9NzEn-CuBxmDSqP+UXJlMTqvLSTDCXjp<{bvVTI^j^@>JwWik6I4 zL9^b3+eZcxWQXFJ!U?x4?~YwNON2BfJB*LljP5;e1h$)-8;nTVPp-tDt7Ry-ObPK=;tGQEA3Kah^XI0U#6`S(|xl^IU!flQMePC(ooaVj4 z6AjeIuvN@8Mb-XI@nAxv-PCGZ^>(|3Y>?5~5UbZVma*tQj7DCdBZIOGbi2r%ip+2x zp~k)(`A5Se3}U3&5^k69IBBv3cb)e8{Ypd;rFmL)h2RFdPJAmwjx<%dw-y+~Bsq%C ztR$yLJhinEHq3Ur#Y9uinnIZsQ4QtNP0{zK0Z~o#x-}ZnF+yyCv(+G&i>Ie2-N;iq ztW7tC%rc5g+M3ZkoiL#{$v#)@ar~wQVwDa}<3Ta*cDn$mL07&4xBkOO-08>1$GTD; zzzpoxOs1507;HQ_u!-VhK2cmk#JAL88PKW5#n&J>i6qQ@X?2Zxc2#1tQVz7K)__an zq0@1VN;dPXmU^3kgk-^-s|!G-LtPD<$IL-6z|t@6h!9yYruj;5x7%+As?z|J32IXe z$;uy{Q2TPeRcReZ_Wf%#?{81gy1u?fBhh0_R}SWg#u_$q^ziVI(N2TL=c*Z41{!~s z--c!S8+6Vrmv|VZ2Q?=N9f@{0;lh@u*G=`b7b%Zw1-K_XNm!KDqSNDt$SW)G~VC`zlC$4_Kg z(#p{`&D#Q%04L}{N*G+3Wt)j+Z-b6Cl=B3C4m^&N)@aio^!Wyk8c@RFjnMFOFDF=VMcPNMacsuf`^BP>?;M@!D2AiAh!va$ILaej8)om zT~P)B5touiGsg;#j4Y=pW1#06gm!IvN_M!P7TF)) zPnrtkszfa38?f`|Hch36p0p%gyg#t~d&Q7D@7l)qaWfTL$HP5AE6{Iz))H;aiT9!p9LlBqX$wg&v`F=e};Y^2ip$g8= z&$AD$N_J{Ib`Sy;x^S7>96V4JX&V&KwFEF4v=`4@Q8EIFOOFF<9+^Wi=9e#3&JBY$ z^vaeJjl40PUR}uYc7@@pFgQbud^}L2*n>2SQ=tw!YXf7ZM7L|e|4VkpYgvS@nfVUw z5?2?9QWHK_sg&xBe579#xLYK#)+-fwN`qST1}0xcQCfuxnV+f0yR?Lu;-EmnGoVBx z*YyZNfn@Q}K{chR2YE`@w{PDb9v*T@JIUf}11|q1*ltY%W2&PesmvVD&4D&b3=%&2 zV;haRdC=s#&SLI0=fFgXRY{H0<>Y<`a(X5t^IB9TqK8Z~yFvldhb8TZ z=aJ`)@~9NtSYz{R39}VdY5<0|RB6ghFzl>k38@r|w!mf(IdFwm*-D4qZU-^%@$s>N ziSpgib`-LD+8Inr2TJ1*1(WU27*Toh?GmLT+N*jla!b<*(548B_ZkbFAzX5&Vn!rH z=TtVm7@Y6#?^)>;=_EfMNK3G(TuP8##kJ)5`MC{&XPr^ zy2+guMNtX@vRvB8M!PAnvhg~Llt9PUxTS6Qp%P<_Q&^W6b ztd^%t9UzaA!3w$=Z-RG+W+_p3%2{7v^GMPf=&L$w?-BK1bc zazdxDp?4{YKwI~WCMzO}>p9&CV9>x2UHc$_M%YHUrxJoEn?9=96XQdA{p5QqN>R|& zB~6>b<2C?V%SvKCi~UA{lCvDTqz0~&z#xZMC>6ED&V?90C5LZC<3wRry1m7i=AojJlDEe!!WNd5+ zQLE+}=OIq;knYk%@u4uFIWVvPB~K{mBPgztQ>YNuRNDAF z-qmG=Y`5EzRmxlvmKkonE~IO$VTlyR+~3!MB7tJ9iIl~lTWB*O^=5^Nm*k$pK;_dW zsZ5a5+UI)N?<*~Ani2+;g~e=MVYpaPJRWn~qQKo8Wo~4PK^GcIQS5d*G|n`qX>-Yw zwq~SBB*cT-B^)I?kX6u}npqUEYalxf$Uh^Y_(a1eRjs6f@tOKPRqiRutkBhHkpFMJ zXA9O2>S({;(~(nkQ_9*9;i|^*rW3b6T^MR-L9?qGfD$a1CZNA}{Xmp_b`i(C{k(bH8{BUUA_ z-EL*^vSxE=OsTZA)VVbtGxTomw2Xy$snm3>M$XR8Xwsuv@h~ILkiz7MCau0dwXi#o z9MySNC}{CKvfOE@9*ACaq{<#+FgrY?42`OdGfh?qTC!*t+pa-fW0nsC&^2ad#Pbf) zauhkg;Q8#r^`3uip5=6Td6_#oFXEh}M|BH>KyjhaxTV-qM;-(Vfv9RC9!S?{HqG?7 z_S}w2Uh?P(n~~hy+@P$Io$?fADr5zU2AMl8)gv(mA$_$WdeOo&cPf+&a0diyTL^@? z(=sD8@Wbeb&Reo@wQ?kWug0%_cRa8dMG-U0P};285r$(?A(}}PBSu9??~jjv}gIePD1#x6SL|*-Q_j2;Ihp2=XF(4Z6Fhv@ZM~z2ppciPUfsvS!VF`AO zX-McQRZopaEF3U6WGbCwEnG00hj$s0*%$=r&n z*W6+fFg8-Zl+Y2(vvm?;gvtSt$%aoV6_f*g>z1D&YHt8^%dJD~>=PaCyi;L=<))|ul|8GOoN3Xm;kY>Qf$X$3yb@iy2pgmLO*HE!5#MDu% zeAN=;w-1zx5FdGvJ1x^A!xW|}b-x;eIpEj6S~1USR!tP z(*;0(-|zRu?w2t@DBAYp<6{H14N44hLM3QeLCv68bs2Y|KZ@g+j?Xipix*{uRMG4q zhd@9bfBc+MFYgbe-HZ0~^z<}n>Re1hP`#N_8WME@9VcV_3iJykK+h&iK*EpI?wLj1 zRMqDd+E8<-hDixX7zCiYsVdm*cHa&p>&ds@h$JDA<1z0E!0GD>GTdRH!* zvIv2Urmn`}C4ed@c}A!Uy1OpL1&8V-( zc#9|m1&FbW<5-#uCJ~Q8+6oIJIZyqrS_oVol(yO`3`I=Nw6VQAbbkmxMQIMl!x)bV z{em)KeA{5C&yl4kepq<#n7&L&k_Q-#Nl)6VQQ&xQV-0C}*mSwH$(@!}BfSzGs?r%& z&XcWu8(L8+0;9Jqh|=a_%mR#tG3L}onq6f-6r&XN*Nls#(O=Yqk2)vje$PksouTM@Of3 zStI<^e!6!FQSrw^v(oh_y?MxH$qldJftp(bG!`23keegAoT&v=`bZOt<=Jkx7~3@h z-W*7L`v!tv!gGh-IF@dYsb;>#?5Wj-K%RX6h%7@&#T-3A<=rEFI+^*EtJMDkLI z%DwRsOR7c#o+wo?dB|uk>e2qk=u)^>J5`btWhiZEA;w1_||NqP8+=ikUkVN@a{O-=!jjx|Fnsj6c*vPV)Mh z8j8OhsPrysPgYqWtFk7=09bN<846G3Mx|J8Z*Li@OIOp&!w4ZL{|5Hv6pZ$d2g*5% ze4U{D(V@~pC|3v9P|wfL$aS%jMw7-oj6IIRpVo311yxkLr9rG3JXA#Oa)qfEN*g!K zCnSenqz!WeE4ZtxD|&?0o{?Oj=-SvRW5}<@!frGvU91+0RV$C#sK@~p+6)v0a~ygE zIzo-|yh2cSGN!E|;0f|8?zF{58KRpH(%IfDQ}W*EBw%UJ)|F<>MK@<%6fX(dq6@kjj^x^6IaTNl(pDPXM(z^mbA4JMgz;1W-_HFq zr(@=Byzk6i3%-I=CJh*iEPiZl9&y%dpskW_*c}mG;I#V62cO z^O)zLHKK^A{Y)gIUI*FA?O7>IaCdwlw>51?u19MDW!qo8uhDAPvs+KSMj6z$QW6e zM}~U7K>C_WZ%{%6GddV*^z1^AgZ4)1KS#3P@0o`0-@j)`KfpMVIcsLHAfkQ%l%jEz!dWyZ5A zFiA?8(C{f?`oN9UO*I@cR50Dfo6qdR(7|ve6Ne2A2us*^RvKUpQ$I~a+Sn!-3hEbm zS3NdQ!B|6UkAw|l&3a2nq&ye}vV;n0iZTf$cx8@6O!$h5_d6dN-a#n=I+lWjgICPB zPb;x~N(1Yll6BElqlQC@qQoPj=4zMW4KPx8mQ$NmZZUyyqUO+wq9_7w=hnIRtpvba z2{}Y(%mCa71_}Bl^gCJI50&>&DUkCSx3lEqyi1_8IJDGBHgLEq4Tmbt1@~$hFiN*7 z6lDQ0R@~g&aN5e9mbF0Z)~QBm?)40f7H+~*Fw(>xr4R~S7eEX~o2*nCnGl-cJsw!6 zg{q?T(%6xRtAZA`&0Eu9Bu56n9Y|=XqFhSY2;OeD)N85P$$CH=Q*)yd&=?m=8&K8L zfUdg)Fce@-*HVxZ`io6vrz8OZz?hXUig&l$jZcrVJO$dKOOn5DP${MBG#-^&+DNQ(gLMFs4rt?>I zOkzlb7A5CN72=qQB;DWNQ%YRndeekv`B(~-(>*iVsGz~~yuZavEX>{K^4HE`%$FFtVT1HWkdQGBOq)A^i2G%8Nv0z#mQ@@H2y4WNiFr+9-31I$$ z=%~BolfYf?W^_}e`EW*%;?#*L4E3&P*mrk#w@giLaDUvE&9@jOK8Js z3$c*_j%4p1Jt*OJG4?BMTS}P~is)+-_IOrH1C!=5j9CcFxyfmxBHHIr(HE)37?^yD z0o@p@Ya6AVn>;PZnr@vaQz22iYmX81?l9ctPQnsk0^)HhItVy1&3BivL_&?Q6Sbj# zP$uO3{9Klk4e0-+XKDN^rAB0+PE#(4D`oOB@Z*8Bxm&CwbX#f?sHiO8cv8Gw$~hfu z0ptKO%r)!DbuK72r->+3Z4FX1nW2UgWM(ltFxS;VJ6>8i#P=f%K{NzSTYIu?)TO029p7@NMHv7V zl@&F!HsFZ^xl=I;^Weg&HEhaMsAZ`#Ay^J$6*JW#FUlmCku$3clz{@sseMP)_ZaGil|3)u=$0#MPk-|rWGZx!9P15Iahr$UKBJj>DyttWxb zlDXcljN$gcOx3r-hSB`79f}f<7@xPa9IkyQh=IJYuBP{G7!n3!)AaFvuct zBzO@{kt1 zEF=WgLMR=mY{xRH4NW_(fTkLqAUTZOI>%(uK7)u&3`>g<^bBqm5e~r+wb=fdvu*u z9imiRk3^)zAQ6Y!2&5ySwy~laFEDU{3E3lg!j;fWKn0lPk(FS^?L3KHqmtWtU`W-4 zyF9~9w6Oyv9tth_yu3Tk2(#8vX~v?+atUpchbC7P2trwalh&p1tJZx%~#yqE`;;jy9 z3Gyn1(28i&(wGs*+)!M3czCEiwze`99&L8h2A8{RF3k|M%4z4+m;r} z3{shF*_WU@RVG2a3#;1>-fp)Lbynr>Etpa0)%HnQE%epW`KVRs%RklA&d<+vX{?NA zZSux=)Z8~a+Gs06jLo#a*g)Rf@AoxEIc^&WS2qU|^h;w7*pd^baBn#_KN&$q@Ko`t zj}GJ*h+I^+9W0}FU1wNN0`g1$eI1{bL6l}CJ`&SkpyYf#JUmPoJxOT>Gzqkgwe2q; zzt`8-YwHfIYp}wg`n2&@aU}~p33r8ixb?!Y8@lPHED6oaIY|v2D{!xDKqMFyLmv2X zVEKcF+k?S58*rnpR7~Pwb9%VBqQt{dt9FgLKsO)8St@oM!$>8zsp|<-v%8d<0D1RQ9r8BjX02+^+J(N2w%35IXhw*`TN~7>W zSmGU3wr?kL8Sw=BA^B#Iin?1?P|gEG|@Zi3R}Sq zoplB?e|H!|lGh`Oq9}z!^O&mV)+#_bC##yp;S^HPP>UK!zqLeB6HOX~jofKThh|qG zL2RHp5$yN-DynQksJ}&9U2MIE3X&$Ln~&o`dCqs}3Dq^VF9RbH1IWCwXjta7=*yUl zNua3`rqQVa*K_EoF$%OY6{78|_cR1Eh(TStsb+$itA0sQlzP$FP-{j!>@XwePRoqY zh-D4SPbE7N8MrY!pC)BpF;i)K03IwO5LeKysvdH$ zuC8jd9A+@{>XI#RBa-UP>_fexEC7Tz2o?B$y{<8ejRd}{cQjT;vZRNdqBKuq9ZGzM z+mm%M@nHt6YiGZ9Xf)OQ!JVrLF{*Sx+r~mkk8e;GM&i)cZug}qk(hxN8xSh4udgAL zs!oOn_-42BpNa{0YQ{Hm9&onu2Bs)Vy-2txm30SU26xJx79|4>2+2ws7$;YFJhxH^ zn6h=IR#pWMJZfVz2vdfr+E#7}#t@nf%%Ku8dXgsk7XMRjfG+$} z#f0YtsL5^?7(T0k!~PaV;+Cjxs&FKPc`)W598B)7C1v@GWbq7(c-krq8 zPKzjz-EK$AIuv!<$=5PCq-~g@Pf@5t0#vS3szZ)ZtM@QjWe)0{cE@itaJOQr^hAO* zuTU|vW+>uf_|2Y-W?br!g*KeWvqLY}+^KkR`B~?(U1=T+Qw$cj-|us$MOhb^B_Vh; ze_F&Cc$Q_dSJC+B*%S^z+G2#dDROyvnf3%mSSmphs2UU_H>XsX8A@ZPJ_W$?UxSDD zf+Bi)dP-j6ef;<_*G8BafvA6+QZlCGpu1X=fW9wgz&gSwBimKUGVLT_UBJzK-8EB+ zg=dS8H+@$Wr5q%%Fqaa^56Ql=et#hCUQ@lM0@WDQOi}5DQa5A?^|KBjVf@q91#&E7 zmbl`wu&T>YJQ-veLmz5t%}Q5vXSTXpRcd|@nLQXuXfCd0Yf@g2Wg(p7Z(>?S&WG+joN|a zkY-ZLL3JhdtD(H#8FBO0xkgaPd|t5_Ox6<=4sulXJn{gqa@M?Aj&N0Cpq+Nwj4wf- z(#~8%D}}U!VW*six)^4V|BMEf31DEUH01)CIs@6QXA^c1W-vEZk7U7A-RlNZOK?A8 z<=twg8DE2kF91q-%u-RTY9TbPychI>Zo(bR)O9YOtYd^<&gOfWU<^4wKiBZlic%WX?PH>Uetur< zhK?xcbj7+_YMGlP410B6KS=H4<0I|E(^4+6{+^zm5^kqvgZt*XzDR>HG;*o&=~zm$ zqSek;X_!&*wde|jR@Q5%8c{DN8zA8cX&O8(v}>8`TSCiRDUgvOrP2VHb~&L`7twAd z6k93FL|{PsMB{8=#ae7VDpMgL@75;o-Q3)KJFvFnu+gb8G~M6d=dE$`h`L-ZbvnMK zp;7Ub2@xZrgb|6Zi&ze{YWk=M^rPggQRB`pRq^C&a zD1`6dzvoU%1&ERANVSs4pJ=hkGC#UJ8~oGLlkVCGC>AXZB@)gWpoBvq8w)+5R#=k& zxh`YNM4J>-oLp&G8&_9X^zGFiq=ZS151AdbZHUwR{l2K9JcmMy+2`lyCN1qzH4KHV zhEIwz5{%Wix3{`DjfX*8b?}LV{-_wjnx!#@jtpp~TQ(-tA8OPiMahMXOKSKr z1}qIYM`R4KF5x0eux+6GZSGVk%49HJbiK+Mr9G9DAck#gI6^`x6UdN|J@W3*DazVt z%u=ERFqCmYxBNywhESf!th#Y!%`9`?U%fU1k+2w_pPw`C9HE3uFl=CGok@(A6{Q4d zIFuZ?UQy=e>Hrog*~fonotQBWFRcLedI)s3aZgL7YW8ds-x(_aPq1# zB<$p%_}AE-q#|QN8M!bQw_iW0roCM6MgDC94jUnA!%U!N3UFb(pf7kjpim>jk`h z%_sIIV+J*9*y>D~19UwN9lRdQh5u@+yBS%fnT&LhfKj;3Ad8vw6Y#R~^2J zg2%IJjjWuiN0mWHWK`YcsuYY=RHv_`#Wu!nx1+1zN|fQsv_J;N(5)fDYT^C+_hVGh zkW4gEw4x|VvGBlXdhAv@P%|1HRu&LVv+uuG0c5c2>+4y|N@Ct>jVQ|ifisuM1XjdU zPc47KV0KXK^p8;gWhEo6YQnjDh~cHl+$qW+Oy6hS32H;SZX+st2QEu7bgLb&q9nlh z58u9hgYeVX;Gp=R1IudN?UnWrzYMhMj8V1I){nRgE6_@Z--m|>Df!%KQIv^6-^{qU z5DR3G@pK7BWBYa>R~nQyp#OVvW0qJ+YZhNohWGdP)X~*m2u;T3m6IGB%a@`k%6xEY z!?5}N`}f>wDILh$13Y1>P^-Fu?&S9NmU2#Y3n+03%%a}muI0_mOt^thm=oFBM(o`ZB7Z;*ytzD^- z5jjJofdfw^DtmP&JBL9ZL8c&-YRss)K?yTFSMshjW?1gLB=;tCNi<-ceH3LpSXAoD zr5B3j<2UIZ4z}^lhhcK98C+&j3JK_ZfBE#fS0C=5VvlPBi#n3vCXWb z1nvFidwyPI#MbjhF+lD2`@+L9VF;xnvF(^+jFptU3KKJxG>15`l1&?1u!_Va#X}!- z%{~S+04+eJ4My5h%HA$Wn4wG~w=`=Fq+Alv_UxmqoRTHLwK1WMnVeoXWNC-mP==+Q z|EoBW!`JfqboW9lQ;bn*?P|Q;k?5w-wi9kg`fmh6<6EG^?A4s+z z5an2MP!5`1VRTI!7^$?!6CNHOR=yE774%fXG}rL{>B4ZOsfIB{f%VrU)qz25{B9SO z3FYXfkca*AGBZ0Epu(F^5ZQ*v6Lt%tHx>V;*OVQAi8X`g3h=i6yTS^RTs~yu!1zj6s zLUzo3oEmph(5=ufF!+?S*JifTwih@Hz!mHF@84HD==Fjk!eBV2d}vZTm9#wV)0CA! z!)%bT(}E7QZe)*33xP$f7`#7MG~ngI}49^z&K? z8ufiDXt;&tf0}}qr`jcJ2%ALCI4(!M6OY-m%8?e(x=^HRRwGY^X-!e1?sNgfR~iCy z+Nj8QM^nvB^0cR?r}0mVhe7Y#JIi=IoE^xU08D}{?Hw;q^R9wQ8{{(1R2l%&1jKs? z`86(@I&8Pw9|s!SPo$!tr5w!!ec8qY5?98fVPo5a5da<^AGK$dKyoOC09fxNI|8o( zSr4YUd%rtsQ>W@d+yYp*Kk7D_qU5D*S3#8+BWbVd6-7}Bgu?dy{r$*8nv}e72}X}^ zoj?_3a;PFGJfdlPP(zzL6*=J?t-C*pl8aeg1v7#iF%Vf=0P3mI0I3zzYdQAeHW-0v z=Uj3k6$R2M`ZAXDs&FnGhT_bfigFP@g)w{6N&{r~J5ZD{K*pZcc2~}!!;5Bmg`y}0 z!U(Zr&Rb~@l@=O+lK=DbbH;`(3y_TZu`p=rQcx@3C{aqrJTku6-ZT^jGjB;JjO=iy zd*SF1bwPU@hAPUP79}T)^ouTYcXyXNEk$sCey-woEtuh(W)-tBPL4m%PEnMK;N(bh zrzJmFp3~Sy*Xd*6Sr2(7E-w1=$~j0t`8H{2>d6OrE6Os^yb~k`E-nqzc%~UkFwUMB z`P<&+W|T`+E-53C&@Ncx=T1w0WCP;i;Xw^As{qx+sB6t^7%9ql*e@U<6u$Z^8BC7* z{T~0%TZVW$sxo^T#D-*UnUm&ft!=8Ay)jI+yxr|~>Iq&rs3UdTuN~7aH1C1P+?rp& z*hU;5T0M8{`uZBudrNCBr5rY!v&}1Ku20}k<^`LGA0rrLb)_;zPv5=z77(&gKR@64{+d+yF&XqV5<9aoe+pmkYk1x4eExj<&p-eC z_19m2{(0S39fOJ@d~f)fk$-YN)|(_&`p1vI|MJVP;W9C9`SoBe{5$TA%kSBT59er* zXpQ({{^_(^#bj`3fyY-$+LfJOoR5lpexNSDd4Zi6ch+1LxLm?|V0WNeY+4&^-2B z|Ni}l?e@3ByyGlP$MZja{P@QoSC^NUXJ@}eG?JGOp1p?a^9brH)8dYzm!Wnd4;A=>}+4GgYj5zY{x!8NN5AkKEn`X1OZcbX)Tge!@sX?FKbn?+m|o*_B9y9e*gXAbcJ=e?S)@XpWpf38N?hZiBsYY%WULC6Vc;*7dtD< zcdxHH!i8hs+f%Jp^6WI&DGZmDLuG*)M|;4>TIhK{xDrE(af>fKZy(H<4-a3_8ZE)Y zTP)YtyZigU@c&>fbP8}|J;!&ASzqDiXJ6p0K66rwDVE;XL14z9`u+R&(}n70MB-1b zbUq~5e*=$omVfWXk-zsBzU%wRU7e*|TxFf)cfa3LZ-5m|urxZq_Y|5nYB@)z&Rs8G z&wMMu2_~t8zH}DGCo;$Alx|#Le+qnkoeLf0HW`BYE z((`sD1`Vu3fBg8*L3QISpH3Ryp5qgJPuHHE8=Vh)yB;GLk_6c!A|uXn?*2~Q0?YjC z*RTF(267tHw(T^?_f7EmzK6VkcK`eD+!6|1<}V66J-&#Vmw#R;G8N7=)ye2)_y1I5z4(HiS|D#fp6 ze0#X7l$_b=aPrLUc6;c6?mPzPozP?X&(r-)Ul(wH&^9nQV~EB;>bxK*u{(=yv+3^X zY|N**@+jB1^XM7!f_Y3fzZH2j0vi~<7>oGq@L$Ef48&TQ~RFL+o?2g z7VJq==hhhHpD$m&L=?FFK*t+BddQwOiCTm-Zt0FXrT6x_-R{%P&CT`ob?3_6ZuehD ztgVxc@hERygeP%pF4*`V7*(MgM+fn>w70Uoy!_+t?hf*5Kr9c)D#2O~{nMXR`(4iG zynXiw3H{##Y3S2t_;MZoy}#Tr1YKY6(3|kZ|L~LV7>gbr_Mbl8L?re2)7dYF=le45 zD9OGJK6f#C3PB1#rcCStbi5Ah7g0W7AnIJ~k-MBZb>_>v{0x_~KWomia$X#MMP!XQ zzc_Pk=IiZIMrDPo>GgtxAxV!uE@#F8u@xgw}8C71de>?jH7h{!#Y1c}C z_g%Q1lg_Cc*<0X;rTVYNE8g;gCmd`!&O5ibUTr7r72N*)`#(Q_zKkBHW+8R~Iv?(B zuAU*n3mYCy%c$CQEn{Q)VE1)2-TC|PzfX0ufoih<+W8)6-n}KZaXrLcMF0HrkD=)H zUKV^{C_NPWUAv7Ze0brU-#@;?BC#wJ7L5+^@c~)8NdGyI4BccvK~U zX8D4s(~UJnZxii)&|-i8{lc<4eS3SK8plCrH_FqHe5rN(XlW6BrEM3lyX6OQHnZOA z?KJov;%wOVtKT?P1ikzp6RV74E{XK@E>Di^GVJ{5Y%1Nn*qRo9hjQ{V`(pwx`U zjG}QqeZHjnZVCJ;^2wct*txb7yzyKXc(|{FY&_45`W*KqeP({IA589s%3^Cz77=@h z;bJ#48+gv(40hfX&`tR}$jOi9m9i@bK_Vhy?g#p7&{-YsI>MlR5S2d!-y8V;`k`(L z`GOQZyyQ*Bv;p&iz$?N9<;^cL3ueU#8p=bG9y?lb(va#uzs2L0`nHSLaKYhB96@;t4?C+b?heTGl z@A>9)1{GQ;U!J56x;~*&SgZT<+kGG=XpeKHyKpd@3ifB*gWV8H40i}d~TytTB5Nr;9%0}T;W>i&zEI+wedX!D|gIC-@ku9q#;ls zF&{_nTn};n^$ok}?)Q7tJ7&+{fB)TjPM`-l-`i7q9xa4jjJ_`BYvgAbMP)GT?3>U} zB-N+S*Vtm(f1m^gz1Q)m;B&%B9ad$udiwO~)2Wq6xBLU|#qjd=>sL&6mZ8F+v~8@v z_7^yfIWZ@qZ69V*=e?1|71KO6)+@Y4gknK~V1Pmi_bnFe0(X{=uUI;X=|24X_kSK9 z_O>Hlu$&z!L@s{$tEr7;UbvcVE7I zIj%qhZ#?8iL|fr)l|UGtMd?FUcz~FGN_8XKOV=f?p+be9Md2_Tq)s9 zCDcyuWiiE=kjS?S{4G|l*;wxi)Sa(|#8hP`@%A+VPM&YAgF4R~RuQ}1r_=2WUq(8) ze)}tik@NF#;IEUH{_)4vUw=JdW{+%On9D9MF7NN}4?#uFPE!)oHhfu#DXS9)y2CQ0 zzk+<9quY+JzRZ6*pFiw%_VuURlpEK@fwt;wqT#0E`={^6lUq>o2MPHebP@yl9A`%U;C%Il3XsEM|M$~pz9#HcHx-l9mm0jk|LZgw zVL0WEhhR*;zJ76Z6{GIHs(ksl&e{;@|a(S9~gO!{ZB{wA;&_@ zIEL%#eRyx9b=FIu*n4krmW;C;0?!G*sPnsR3Lal3j;96hb>_mE<=$s@GV6O_WQE$d z*x#M68~F*m_YJ9_J`?wF`Gkx2?HY{Uwi9ch{4wBQ4SiUyuKx6wcIWx;(el54|9;R>{9@hWcqtVE0V)G$H&u{i!`2FJI;#65`KHT}DUyr-PzPz8@<;>uajhmqrdUpEP zR~WhLpc{Fc6#9&%eSdN`m@sdbAsKgfcc>|UP&NDBaKG@CfA_CJ$B;lh+SmKi(EI5; zGmw&)CkL)^KHR?k^`9;yG{=>lm613g9|GB(G`!PIE^jU@DbY9QcGC9xJNE+q=l}d) zx3{;!>)#UJd0k&2JBwmuU7UrV78ITx*JFyrG=wqM7?(P?bPK_Fl=I0pfr@zjYnpBf ziGO-}I!>c6(#3}lAFN@&XSb9=*#7zF2R?uQ{kP>a>n&#i4cORp8`KzHBCA*-fb66? zdHo%86B6*(Uw>g>L<#J6yF;YVPCAFS%mkmTn=K3G-B(uMjrY zcV}fe^Aht3Jmd{Yb5J)GuBpg+c}+>sxu9D_=z|#c8HmQy9!^T~phbUwd3j0wzh7DH zOaI36JwCJUj06&Z+(E)QoH+Ss=TiSjduBb#i8CX<2lh6e-o|!fxzP#z9Z{;j%L3Os zes{_LzE|{CqO%a}f66uChdWyAkk)0_^2uX|D&<@*V7+&BUmCao&o|6?E>5pEZ}er^ zm+?TU+LvuSsSRY-EX-G#%JYi1hw%D?&+_G$FJF$rQn=zceZAwkGtNe3ufia!-`w1M`}WNxMW19@KDZKPb+GUKJt)MU z{CKGPUyk;5o6{Esx`s0iX5LSJw@}$a8o?>2dJg%`PhLt~q8~=AV zW<%xH$uT9@r)hS+y*GKz6mELU#JWAOmDYJqxRkt4aP4!wfZl2-40~(;?J~NvVKsf6 zJ_1eDOn~EQR@&@**}2#-0Fki;@OFJrHx($H-oEBY8%p44`WWgC8*e!M-acqQEpVls z24_yY*P9CgkL2tw0ST8KGgElXEI0mK``)`TE|x63!&r)W;SdrnU<&p2LCXLB`;k)# z1_T)#EPrl~ezk_*g%q_3Kpv*C?Gra2e@86>jgWjC}@^%ec z^8ffB|HIraF&nMx1f1B^(!dE4!k|;V{Eu~H%GGpzeIfkJ*AMNMt>sL(NQV}F?~UDu zK*&5A>3JK5FKcEaKT3~d3V)K@Z4#dOc9%G?|5x{{qCk3jOV7R_t#M$bc@9HEbT=k*f z=~MIL$B&zv&xf59=X-qxZkL8HwK3Hi*+fq^K92E_--y}%^JHP;Npm1E$)A%#hqvbXdPQ zo%?!|YG*uLq;~oEZr=o6>bJLdrY&aV_x_c-DU?$1WcF?v_WQ4QcVAB3!9oT5<;(r| z@BiSgzVy8P{>LAG>~=fZku;0c=|Tcw>FVmw=jVS-+o52|yf`B~KRFLB$!FKAJgtwN`@y!{Rt?DqD~2-D=d<@GyWbbbAD!p^CdY2&)ye%hc0VB@&g zV|?DZ#h0+adwofbZ6Ses&3YGOT4Pd(vEA}zFr1$5W#*`e3dQOV$?&W_?Skz-Dz2Nq zzKa%&#;NF?Iy%W(ghC*;g3L$Bci)(1_<9Uz$=ug4<_=%--qIgosuymtb_KahfGgjj zx+zccoE35M*uVaIuyp?6mxio zvGWyp>De(C?=UGCF{yl~lDR*JlY;-@S}9_w)lCdWxjzp?oFNj*2s$Gc*C1H7Z%w@~ z%($<<+`n@YcWtY^T;^9RIjYI-P&@?IdU$NfxZdTuNVo_Z7W z3g`8M9>NNG+5N-{7fbR46(2R32mfxTS$MdR?KFoo6<@jbpVI2_1v;=pe*5(4#-B%< z-ntuBQxWA8-x7R(4Hv053mlUn=%OuQ$U0h=#Z>Ow$JE?9&!_O0MowfmG6`AbL2d}0EGWa6j?dHXSWH?jn zd`nEB#eW9fXp`{9m_l=WXuj(TXrJ(WUnAN0uL+m@#(#}-J2I*k4lZD~n0!4xvxBO} z`Fl*NIyc(ieebn@4-k6wX#ocAdiew`9C`~d{Cx9A=VkG)JNeKv@leZwdrv^y*lvI9 zy=72bO}j1(B)A3*?iSn~g1aQR>)}K)_qCe)>bspib~E+p<<>4{W%nbFPP5OI;qYj8L9jkc8u*aP`GVrr`d3Ihv7l_GV$ z!)jRGXT@<`x%l3MRuRGM?8@IBNkf+6KOUsa-wBUt65q0nuf0J$5{BODFuvXL@@+6@ zV<*bEtI9jOq3+j?V^c;J@q;3{0Rm0ZlNYV_E96LNt9mTMaxh2Cq6MO#r&0=+71gsC zH@sHNw@40o%pU|>vmHzr4)>1Ra~nP~JTIP*aEWRH6~IB8Gj z&kW=X(w$v*rwY&5QK5c;u+*t^db25bpJ{b|M9;^rXWZ*L#kH^$oD@y!Ctdoj=SVzg z=!|XxGL8v;Ax}AWFbLKswZK}v+O|9rUNiM#u<4%K_e+p3!$=()H(WzmK%>FBt!di5 z*^OqS<}NN?6W-@73Mt~nI%D{lmf|&iNRb|VZ@&J7IW6N2M5JOQ&)A)AUJGO}v@kgS z`QYBtNzE!i>J$ej(|Y~uN~8(wDiyK-g3a&rG8F%!8&~0TcBHRnL45a_r@e)BG#42D zJQRUG6oOt^Ef1X)YhU}^Pu1R!G3YhVPpzew;pBj6?J@^5+1}n@(IgU!>2634)C0N+ ze@M?Zu-cmOx>>B-$qy!@A3nW@}uBDjvojt6P*<6 z+t-U{9Vlfo6tT4xHb_ex6vD8?O-a4W_HaMuQ(m=4el<^&)#bP6_p65Vk#FPWL06kz zQP1-Yy574&N_`_G4~x6kRzf%g6=uus?chqsq|W}-;7EZP@x9wIQJmM7vf5Dwo-})r zlevtm2l2va2lC#A+|>~(mNurn9qE45KqI1!E0g4jk?8j!(QxKjUmCJJth+Ma$qyYX zbx7W&7NO31Xx;~8jHD0o*1Yi7wO$Gh%nK?x92N?uo(Mi|OX>w>G*>Ph@Od2H+}uD^ zZZA()k7V;f)^abv#kEI!N198nj;?<5q8|-A*S_gNyA0bOm%MjKebus!PKaExh;q{S zA7D4L(p7DVoy~bf1Ss2`ZddjdmSyQ3uQF2aY% zn+}T4Jb*0)T_9HEKysXtuOArJMswtDZNB0d{*i=aJ-@DH zJLHth5p^nctwFC*XAAM=L5M~*fKXrpor?YPVfRf&q{w;FJSn}HslO2amaX1I4cHu* zbVAsY8}ab5Oo3>TNR5WLJeCQw(9V+adK@-(eqoXCp^rbDxsat-58tmQqx)w^Fw6S{ z?zJo;BevU}kz~ki=eA{EVY#$?ZxExtv9hxA>-2H)>8Nw+bWFc-GF{mn9Aw;>?xwB# z$$~TU>G7s)WQ?_a=bDDMY4%2hwo(13arHYXpfkO}sPrN)p}`%DJdl-BdiN|qPa1b6 zwM>iOPc+tp6^15)+_lr*|&xq`@RN6U*5KpkK81FNX6x6on3l633a8c68rdoTE zXoF4?k?vtKoa4?+xK2{vKbgbg-e)grE^%n<7>o~D@fC2F_fD&c;McRyxpu$Ac}QR7 zo&Sn*2PG>HSOSH`hxq-k|vp$EY5*ooQKz z_0`^~Ta5Uw^BXKbOI0@lo_6qR6vBozibeUDsRVM%*AM{Hr3_iwZ*QC>`N5y&4PdHq zH;w$lk5bJ59LAVIubvay%cSuuft}lMiwS#5MT$m6e5FKv>bL;=M;3mL<2_F0S@; zNvaM$Z3Hs_qHc}$D4xzg_MZ?^I^)H^oO)6IOlZGr{|(4wSw~{#x8oBaWiOs=R))BD zM93HNs+w|jB$EPL92#@_<6j;(Z~E|bMibwZvRs-9pH5209$Joib2ZCD&P1=dG}f`#8==}`n}^)B0H`G;s}grdA}6!XSm@I3%(H$(8K zai27zXiM+0U)mBe#|t@x2A_qC?LMu%6rJh2EQ$pw->sV7dU&nvSRLc)xRtK70EUzh8sn_V^j+9n9nIMvN#J+rPmJvf9iZc&4Nr zg`8N_@kmjHh@HprV}($}=TTyI@>7vra>X4J$&UCy`-pEhA>HRscaCcqTZbFPLCAgv z>4yR>Z;#gm5JQ{hrL#BMR!*~2z1`Y;tD~e4-#d3LGpSMK65nc{w!NHwI$R1nYad)& zSk1H|V0d&<4G2DYso`jsBqRu0!`W9H_k+VEsuXRxZq-IMFXCAYV94l53nNt_gG72Q z6Ore=XrnmS+ye-AD^h#UBQpbGr4NYJ+1e_~z}^#F8z1&7CR5f<@cIP#NPaZgd!M;P zUIiq8S1}jSOvCA7mg3QaRTj^BK=C>^Z8-dNJK}^=XD#07A`gJPTvexWn~*tPHa3!HcmXv52>?f!RP~6<(@~+lE7~>FVAixAQFTaOvCH&bA{lY`<0Oj{|~IOCu9Mv;?Ic zTo(-c8fBwQl*0!*KO=cQlV5hi&-b;*xwYzavlD5ATDc<+tD>#6f~R(yk8kiM#9p=$ z-^;|7oUOg`rAyDrrZgRwwua{J zB5CUa_F4_ZbE0C$^sJCY29i<0XaSQq6>)xAdr}9Yci?4R(8x?~MxWS)YR9$^f62Qzy zoFDf3HvIVc+bvG!n);r*(w%re?Qcs>`)yR`*G^B4*|ypbcd$$kUFzzm8R`l95FU{~ zjq$gHNuR|^!WS28`qkmMAvDICyVU?x8xtJh9d7pP*GhQzqC#q=p$%t>GJ;AWnq(i z=i5C(yHG*YXX4Au^4h7l)zIZm&FhO+ApuSrEGp1n_qrbv31s4X^77`pFP*x3I%WCg ziqPJgh6gfax;+nG?HM;!c%(!&Q^|2LboBLYU-o&t*b)h8Yn|_Q1e|Xpx;DDlJa~W6 zU+>x5`IvTKmwP$^5#kh@3@46vUh$-zrp&2YwlNL(`P@CcObO7RJ0NC7HN*l=88Hk+ z`vjSuh`^O8N$U#McjTi21R}d!@;h;JWQN=WeZBiz18Z-DC~_0V8EFyLn0DXvP~%#< z2k0Irgs|*4#RVHnM;~;aKp)S1_q%KpGKyVjE8svu<1sofxY{;J7BqSxSsTx|OB2ZnWXHL}DyTK)+xG?{~x3|6VNBE*JJ%dHcJe8hqRGqW= z6URqFJ*K=J8E}(?z|uRbl@9_UYa~5Q3))9MPTPRh>t3c%eikRetCts&rq1u(&Z*BU z$uA$HV1n@d+FHW#>DI|G;JWd6r-`oQ@Axut375mkNT*0|*W>qPaQbzxv;T5jx-%-R z2ecoCmO#c}pQg~!yfYl&nljgdU;65%O+!G(?Ub(c1=m8_^t>S?+_suVXwLR_(~si@ zi+x4s;zUp1Xb&~Ao$;a@;ocG>6g;E7+8jjJ_W8S*k8_^L+pZI%F$ny=$h}%BnlUcB4x*c3IyJK;c^a!JHbaQsZ@qm=u8WP zczxKC>ow2XyT_(Myw0mPkIKp2liD;akYIv6id=en<9fWq@wXgBkIWVXtxZvMhvRpV zd+ZkcUWCi9YpZqKeX&QA*PV>1h|wQq5D>}bPv91o+7g$P!LP52>J4DPQM&2P$JOHI z;x49RanAcLJq$ zQ6k2mcVB~QaLoHJw1=msc#SR0t)Ye%65J{$I~*mUzK7`jGNWeFdTy0~38OFH3SR;2 z)X(2b9zxxJ26i)2be6`FBBmYi7}8EQuIWHS_8ZfJeqrSfLe+C}T?G*n5uv21SsVr> z_gXTP3Z64F#M0>a6&>M~n>y{nv7@$K%BkB>FA30Pm~$zgxi)cjlSC(m9E@JRw^Sgj^p7aN|un;w)_#P|W5 zN(TTSUN|Kx%cEXoDx+y zr$0!4Y0avu(^#mPjXm>&y65EaF|V()x5vGe%O42XfJz4@ z=hXy=W)(X9Qrt>+fQQX+hoHbz|46#{X8{}iYg1MFDs@i{-O72NiWYC9QXKoSgNu=% zrdbnPr0?bhX>?@@$D(OI^h4_(7y(hLgQIT*T#(GAzea?xaY!(eesCT$sWPjt|J?!c z4Ln@!K@Juv{J`mHM8-f9g+^e%1c}hP;`pKr+-ucT@2Cg(_Hui>H(HTe(9o6hG-Icf z3>KE+gurqnrMSz?4POGaX{5CW#n9~gM4!y^WAK&3_qvHMSJRwOn%ydJF%-LdzYuG zG4T!&GYYU-#p{<(z;~KGNOtOUrDA(zZ@K7MI1yAOKStQ?c6%@&#GU8Wj+>Z1S=(x* zs;H;D(AcaK4luf>s7g>o5Fw2Gv(AS!bLmtHnsj;a}+$cvpsX(#K}Y4;?NZi1^Z=0k<6Ig(|loRNU{1 zES*-uWP2TD$zrp;e6;*sd_Uq-O2)IfBhL1LszM}W71F8g=~_CPGayADCY1t6MZ*56 z)i+Se>OHwKr&#tUdk+&3SzyyL zWm28viYa;Te}Rn@w?x@Pc4)WJcA!8ld@j6FH(z;k8T>3ou%E!meRD8v*KTdY+$0*N z9adhrQ#YAH;b7j!cE%}@_1WC4TdY}Gl>Fk|cN-2#-oBe?Ej*Tj&ZY}DRZ#4kDp(J` zca4R;O?Nh^KiKt` z{QLxa(!Z_N(b0{v*yt<_=%9vCt#B`e0Ns*2zYTPQ!_>E;a?s47D#_wjU4ONfhi9A? zx*X5x)sRT|!d;`;<5*gTX8({_m1%kgWaK$A1uXk~KUmE6b8`SmHc&%nE8-S#Y&hmo zc%-E;ML=EfOMtwtBXV>kCzdf;Vy#W=4jk{o7Ed!~Ti;2$tLGG`2Zu5h5ZRCyrTX0O zlxGPwwR+z@-lUP`AKg4cMy}iYyy)RPB@5>x}NDVXOY5`IjU^=+Jp+8Xjt|}S2JpGngw3Gxe_C(D&k(;`%d@%)flDj6AFAl z^&oO;$&0BQz2FE&;xT!}Vl6_CaNkXeATO`usR{cIaqOG6^~eubha1??O179|kjNBR z{PxOT8u>r6Z`ghKBh=G1qbiT~0EuUpR9~+fN+T37V=oR%y+bnxDU9@*T94iOm8F95 z{k5W8a9Skk2`6HbEV3h!jYJu)DT_y$zdI|lDHy%2tu0)G8;8W&ovqoDQ@Y0IiekXm z|HA6W{DT~(2;1=Ie32Fp4ivt1Xq7j6^Y@0<<)HPKjSXWrH8+;89doJYNt3CqL6Qso zH5{2|8~89?2_21%GK5kOSl0JPlzx+2XB}oIEUyIUqU&KKN-H6hD1Iz<0CZ(QKYJZjB_73iv?T ziEp6v#&~{Xqt5RB49OF@s2h(@W+Q%T2Z7^_Hems!*$Xg0U1j|4 zGN>Z*^;)zu?sj%xPir&b{pq?9jqr78 z!^k)~>;5}hsv>Pg&H9;WvZC6X`&Bv?u9*yR2B<5)Vm|2E;UuG>uF-!@v7x{PwDlFLT6n-~T%l%sS!5#Z!IIlIZC<=$JK$GuRO7^-CZj9e{YloQ z!V1v(m6K~naCY=T@%Cb~hP?jz^QO%8j1BdVzbG-Fv2cffzdb=+s>DiVSJwr-8~uEY zHbC|QU=R9fZLlvof%rNmqmTfGAG7wKp8oL^$}lK6q@appS)yG3vy)yVgCFGO6;f_m z$aY@l4`1{e{!Nv_u&lE+b&*0tASStGG9<`8&^?<7*A`01U^&#`hCfs<6P1AZy2^SJ zCs6BVgsPbX)sG?nAg7Oyb}2TD9E+`5pUKJ&eX7)~J7Vnw-KL+aqS@m2Szb30v`Z%D z%EC;-ip$Zkq;w^M5%S)h%15nTH+dxVyPNNwH6>C$r<(66G6k}_!}Fq$IkPnM2qt^q z7GixTP*G*eZbie&sVRwD`!d~(`NLx1inUZQtx}H~vZj*ZXtzx11>}VjOq5O|?hSDo>k+4&?5j?k`LazHk80XL={aiQGn=4|DkJ zD!qlGKrJEiu#qDY2i;m16P|)FVvjjI>6VVBiCaEw`=&;gWyS^R`mKnc}U+*lwy>+RD`{R1nZiBk1WlV5LCl zqAq)^Wi&BL7YVJNH{1%wmzqv$9sht7&;4Nph7$U4t+7|KISirX@QoEuLhnk*w!U=) zTvOX`?gOmldrnw>#|Y41r3Z47c&{1z5Wz>9HPsc-+wMB<&aSR2W9zEDcY(#hON(9WcnLxY)%q67;4+^4Dplruv(-SW;bG_Fo(wM}9pC*5}x_ z%t)BKE$ZR}EfNQv#YP?MOegY3sFQd1P#A_=4=VU;KUg#9Xgcxg#rd$lX_Vzx*j%ZS z9igMqClpu&;ljGyOi^`Ml8>Z5Q@~oEdgNkXN#+!3a;dr#9gd1bm-6EU5|Ly?sc4&w zRnipFN(2fW;J--|wHf|+xqByaykp`5e)a(qZ=S0Qe63Ns^-o9tX;4L}jZ|B|YmeXY z7WKXFiAjfNShNByEp2l0*~|S_^p77ufE6QntcQ1VQ&ZE~ z;ONs_^V6XjdaRJ5>&Y#rc6qzU70v9BMvHK>r!r@Zr}q1M4br7I0KbkxCBp;_Vxip5 zLjCGC5l-9O)L<8Fk!`Q57VGn;{p-eG?jTTt!559Y7jG^Lx4BVtQg@B2!us&%XUH#z znK3<;m6eg^2KhNSoL>pGhM}Q@kq#|Rg1v!1A@Zx`*t%lBFT+=0+K9s$b6=RJFcKwP zG1DLq508h6*#`(|y6WvIc1kprP@pMOYB6!G$S)a@MUF%mFl3!p3+yeH5FzW&kRwe?&w_VL8MMq? zi}3*Uf+4?N>*4Rc=p}qv`$v;`=y4*k*&fJinLEIW@hbU}JzpQ6XHM3e*?oZ$>(MRc zii_A6^eJ*SN+d{>dS{Rmz}W7uGoXnz5)UgE87tXeXM%z(Y90;%G8Qdm6KjAe2#H12 z#RT;CH?nrd762p`O)E2yB^etRFE0{{48Y355=6$%&dH6$A`Y|#I;lDsn?kOZ0JvJ2 z0;HXcJ&;($tU%5x04H&vodeJwU=JdLTqtE_3j#Qiu}Ik(g8&i$Q=l27WCeh|1*B*m zUOrY~VY2_Mp?mttEE_5mD@rHpOZI$}Si4nRB$=TrG+F9AG?aG_2UM}(8~@=yhd;OA zPb>J-5&nz?e}=<9jPQpI|FGd7HvGeef7tL38~$O#KWzAi4gav=A2$5MhJV=b4;%hr z!#`~JhYkO*;U6~q!-jv@@DCgQVZ;ANYzPOH>kNH4aESL`x!<|}<$f0zC1XQkF*W`x zRS^F>mHRu@Bx7UdU}NV(Vo_8eL%c3G7MaH5Aa0ijG z{H+iW`_H5Je;#G^kys?%LDH%qh^zmvOQm^Oxyk-|vyy!lhP)sZ69c-F>9Rt;;N&FZ zwQ3Z;B)BV=j7fdq_-Ot;Y`*~}w z*XPTs&6gjSQ@yJCdGK93G>Pt1RgE~KN#EptSTF8Q(cvWO_#FwZBv4^8b(S|$m6hz& zHLtz8wLaal4P3y9#N!%2{8tT(@BeRQQG0vfKh+%yR`xcK+xS<*5(7G!LBtt<8-x{N zjL#4q2$?P$A1^Z(F9#b$`oY1>&dJBYN5;;^$IQje#mP&?#>2_X&cV*f3&}3}FT07F zf~1!Eh+xOg#oh|! z@o%tj{SyoO{~QY+4>KnpA0NaD{|gHT8!s~_FFOave+$cB4a@`R0&+0{{B0RiOJjR` zfGvxlgsVj;N<=%PLBUEP7V%MW=+wlnU(#20EI}cjO{&G{-byOyPgFZ6#o}nuyOv+adC4nb8>QWas3k) zFDEl6J2&5duPvHcIh#U;qQ4a;K!p+0s%!$^MJJk0`|LCKA#SB_Wh`%H zE0$Wf(>?3ZJf5+#RHsk=Zr3~URS4w;JXZL^*kwOEr$a*O=MG-uF>oWFA1lNr75@Gc z*5YW3<@MsW>h=5{_u zMQsWWsall~zEh@PZ*6$)Y;$+2=^Kii<6k=kTRh##Vd>ME|L97b)BhdUKwxVWc(-P` z)wH_WU-fcuvApJcGXQ+K&<*vwYpLpZ-aRSv8=(1TwnY3b__y<%4XZ!~b8S&)YFV4O{z;bxRU%kc2gCr2j-95FcGR>U z_aw_v2G$7Vw+lb#Bn@~z^f#&t(!HP{&>fM7(sxc~g&37Y?fZ5s>$~TjZOd6RD-&vF zJ|>xbeLP;4bwAWq_xa(xwy*L9FS0)&7`gJZ&8h+y9F*rN!P0@ylZyK-As*iG zrr4Qw%X*}r)O25vdKem1^zNfhdTrnCcMMrQ_PO~Zjkaq#LKl&#U+718(Y3}d8+R<~ zQPt08(tDUSF0A%^IgLM91P=u&;`9tuz@?-|@6u-~nM`2<1th;-1(lFC%^YbcM$3s) zzoTOB#gp5f4XSO#h}0`CrcC{8u>Vl2?&xB?a<#mqFI)-_iOSR7UKZ!#e6-@rc$898 zCSNY)u;P3I+2D>7Pw(mR)1%m4nWWCnX1DesKc{#31rmy{dTu%Mwq#j%t;8{PCWE1C z_4Eh|?N(V^Ehm4LPNlSljoAua3qcfsxJ;UMyOp7TJ~udV{bO8x~}bfrosI}&;IiUhD~ zl547}_K$I>(#3RRxe072^4bC@=kiDfI2GJ#1NP^G?p~S2u^a_oj@?vcFo9e+^{ zc%+iE4Bc}6tipH7>O^P1d}R(1q?Q;Lomkz+Wz9srn)T$y)aoK6QbyoI!o zqMI`jYax=duO|A^;wDWwaq7fXOx${ns}T+@C&wn*{La_==hRD<2EzTbZ`oBYE&}m7 zHf~KYKlCUYt8UeE9sPW4QWt&ukLR9K7uDZt({f}9P~W)4<2~zFx_G|}cJULLJo#@Mx)90Whu$*4hLjwcVYJC^r^k!sN^3LPlC!#syhj;(e^O}iZ z(uXDyU^SzoKv4s!z3vR&Xb{lC=59V{RiMuFng7|bZ}1BeIzxfkuBtdCtagQ-dm`-U z;^>F!lAxp_eq3*pVZX!8?#IRf>l{EEx=mA!RjOPC^Kaz>-;4;dyQ9V|xwhil)^&r& z?&hc+v{$eNr#;KqQ!f5=tKj3XY>>;2e4@9OzE)CWo51l)Y+SpT2ly$c%pr6(;prZ_ zW2HZEwMn+#dPLl8u92d)76(rvsjWoT%w=R;L|E?Ny5)IxpHIhrlQTs9#le;-tIz+eQNc*~WBZVuNaY32WtY?}`tyutCT1QqrGFq`+ z&v106xw*|IUgtfZO^fD>0)GgODtN|KjP)#MQ&AWAlrHGw6)$-W?L_yxc?Pg3+wtyK zcv%U^N^(QbL)Z``wXlBng50oIi;uzFU^tRC)~~Kl^j(g6xha!~C(AX5lP-iwEv+!v zBD%)0YeIjtQ|^Y_8enFWO?6f`Mdmy{$6m&h#?);JsDwlXYx}BIt zpa3mKeruxb@mt(MZz|fUVmWt(k7z|3@Y>Z)rUgCN>~9P%-tNEU>3rX`m01)le&BOD z2aUh9@aVnpF8`i^+Rl;QI*rJ$u4RXZAa*DG10he^uqqRDhiVl7h;FnW?{_VgZ2syX zTyVS+{|*Wzo^&{eLL!1nMk(KbVswsnJ>LL>?)@1B=re>Q1NFTp_C(lq zyF?li+M12*JaWH$>|!xoY<5^yeYI-!RQrX)8LF}mKfRa&V=p>kE%VjOX1319v z!Uomoa$)iLzxe^Z)1io<*VPd)bMCz3mu`#OjW&@Q^s^OMaQ1a7B>KDZagP_}?QY?@ z3_a6y>BmETp&InYK;+vEePKwpICpg7;{fps4qp@4Rai%vi){4OhcKUegWlm2CGQo- zu_TIoh_d^xEStRqZ+3Qr6VP!yh z$wt9!>T+D7@M3=hK+u32R0zG=Gy67(WPxVz8j3f-20f7=NT^WB=%mK&%MD3E9rQQ% z%44&yK6WbbqLWGUsb9I3;v&r(BSS6o?B~&1)*?vJ#O9qFP{O$C3J>F>XXKd~Ngw<_}fR_?k+46`(Xp1)D8hZFN;y4XSu_ad#ZH z-_W1a&_lfTjbK-ohld*hD8zA*ku$;%i&I|C0h1)bKRB$bWS zA*}XEhYOsC2}azcK{bmz!VMrp8@!+BGeso~YQ(}C+X{#sP>IRNLC|iFE?z3`w?lIw+c z$LXcPCI9Z8y;d5g6uMi3aANhK7a0*rB z7f}UF!-x|_lFx4))yC^#v-^2`_7c{YOS;|%B!x7-ilLGR_?L;_LSZqBi*D|FXv9ZiB0h>pbuYQNa=^Ng74@N#vR0uhE&mv_DNU?N`A2eI^#Ifvsz_JnIIli< z@ub+j=~>uDA-<$G~FPmW51Ut>L8rqDE?g4ekkCN@lhlc)CZ4V2@q z(oF$wiKYOr@tRt`v2#x)n+$Vz=uXJrR9g844xOvxOdTtg#?BwHvnCS3+_hj9%YOwP8@)MrH-`0rB;EW zhqvg3C0?EmpDW_K4C+oj!wX!z^R+xV;T-4k<{s)uRs%zA$WVqWp*f0uLgrM%XFu{5 zXrY$54u2ph&6~Sc8K>cBoRZ$pACr61ZJ2iL}}>5^yFYp)NWu9r$G*$XGL zLf>kQ|BU1P4!sbOEYBttI7)T5y;;p{@P&l6=T5qnGHJq&f7=&6i? z*>-o-9hsw;6AhxuHW7L}MTDBnR8}GEC(M)JuOz&Um_4~p6eua465Cig1<=Yg*GFV8 zU6D7Nq)}_#tQfaSy;-#!7e&{p_p01gRd1DWGv_qvd{$RP7q3py+84k-+r>7n9+9qH zbqo>5^~$SM9$VYLB)tA?$IM>kxGTE$@PWncX-wr>LA@4X8*ntF>=*qV8Pk#>Ho`ES zHKz$f8>f845U|SuDVxF2&>?UQ-p1{elvkj#QN(G(;*?Z@Tzm0Hm;pKrqITpw69sqK ztSoXcz(Q6UU6FTxW)fEH_th@i@c0o!S0mO<2z~~nb^=vZoe}9JB9MO&RDEEEdu6%YC^?DaxpFD`XQYa*i$O&!{UdMD@&D z7O{*uJrGU#sRZ|9s`+Tf@aR7K#gmi2Bu%QqvBS#UEs7U9=f@BtYle%`{I@VvNLG=BxEcH^S*kChuoWZ>M)T5{9Ox3gx z=MrM-(vxO$Snhph;$|YtkjK}e^>eCOH(gVc2A;oPRA7nCV2PTPvMj?b#Q*l<4L$$+ z<7+=8!i*Q?jeM@1}gx-D;)CLf{Jh@5D_xRs0#IQVrnaX0G}`6)ocw3 zYTYDnkI2zM={LCnM&S5K^GP)6TA@f&v5uK~&Pg!k1p8%??>b!RcfB+K;G}7+VhJYk z#_FQ2pb?t0nCVTV{gBSvmw}Sy?|j@_XQBPr+Q9pZ6GlQzPQITWo;UYmawIlcm)0Iew~9O?HLW?@aNeNlbYZo6)mu?RReO=r%7dXaaYcdk*Ah> z(19i5*TqV^)#`ibIdjVeT8JUzEbpW#!}7^xhKSrjVcSF^boh~N{u(}Faw@SUF{=%p z?l;qt2g)62{TcnI2&|`|RUz`)A|J&B{d0R6)sYs;j7aGW_O;i z=R?}g^uCY5mAYqEi1eZHq_yMYyll6lE%72(r`wh8Jo&V%sB3PUD?@r0r&<%O0!bWa zyT_ZUZUdmrm8apz-4(~t_N!agtJ8huR)J=QRbnRmpdr0}5987p&WTu9wF7PIHkBZ1&4f z0+jq(#+679F@kKs@WH?>TbUSP4xrhI#WczQ(W-ab!2JPV2CM?tskbPX9R~8si|9v? zGJ0vQ3%iWse1^%Y_yEUMrj+S9y^wW=>%oT5eJWhHkrM%H;DwbX@$c#Y2a{FQvgv#; z=^Md=%8iaIO#qF+ggRWo`=$I>p;p|e zUDo3V@(XsK_I6O4x^$jLBHkZo#BLSu*1S4CWKV3YIXbVVO%;A&LlU7wgp1i*__~Tf z8LQ7UKc(?Fec(YQ8u0VyM7q@a5<;H^T+e}9Q9cwNuTHEX4F+_`TPVr6#a(BB2Rfs? zIfzZ-_ghE731^bz9~Uv&zF119gzW4q{*0VTZch5plp;bGF*T=~1fK-+^CB}_TD+GL zf-J=Y1HYGzhNBM+Xd_dAK_&Rs-}vj<>JaVl6T68?*gmw8U_R;)Hcs0l5$NXH5G|`u zo995Homvl}BfT%ylT>ZPYQwx(bvNE1DOfJVTZoruzeA(>e!rdY#hV2vL$!>wN>xZA zZrS9tMG?-ZyAA`juiVKr}k0JlMPI!K=90%`|VP?50Hf~Efa+@xj9%P+ducBg< zgmPwtQ0=sKyZg3MF?jG=Xu+wby+0Mf~839C;W+ zwS4sj3!pn^l$^o!d5|>`yX`AedfdC-^$4@CpQU7qikUi&M`TLrS*0oWxCcC90CIO8 zHA-d1S_4noMQhm#0}9JZGkF)_^xxUn{^P=KJjH&Tt_qjLd@$_KKI{%uSast~GD1r3 z!Tee0C^w*Pju}v5#LP6Ja`6%5gPLCroXUy^YWC6|B`&r;6-8af?;rf{=xe$IY%j?Wd<)eA8XUSC?)6 z&A-0t(@*-z`_4N0wuc>Db@gSNfAJlU|N54$S6qL@*}rct`O&!t zeD_oRpFZ@#GjI6naTh*&vwuC{m$&Wkm)YHyT>YS%ZaeD_ufFiF$M1aYZ9mvyulMvH zK78|iKl{^zu7Bu3PkP2>n_P9tiLcxLU;eP~?sxpYc;;u8Ej{*vqqgiGv+|=iZ1MR$ z{`Ab-F52MccmMi;+aG|My3I^|WUDQLXy)9LzqZ5PH?RM!U;Xqw7yn_+eP8|Ab8l<5xVV4(`LEvQqK}^O_H(}TnEIBh zA9?PViUWpoPI}#@ANc$yPTl5lXWsL@kKgraTiw(xJLiHke|6c?f7|SR2i|bn?>2e& z$9}iu+;46A`1?Qa(k)Lp_?Ue*{L0x6dBF4b_{dS4{&nB0-gwMCSA25S!%seItL@*u za+{Al=ioDUy!qJkZ(VcAk5B*b8+Sjg{n_^09)IQUpZ4Fsx$;lDesSaP{O8h7-|s1B zEWP%?-KvYO{pl`yzIW$!zjf|^cYoVy*!9S}zyJUC{oeiV@%G0({oN1w&FWu%?wmCj zY<9n=T=C)Eul>Xm&v@%8tN(K81z$P&uh;(I)Z_QK{=Dy>w8@UAUw7aQ>#sR)i-UgI zKK9g$@3_xJr+(+18=rBnpY6ZFmD|7nVW&OiO;=xb#wTC+i=S-xSA1vFm5(T&b>;16opJX2*WLWw_paLhycJh%`ngZu z=ZZ7_xy!EWKI84D{^G*lZ}OKPZ9Vhu)o*$6b$gz?@n`RS;+xL7_qp$T z=o|L^`f%mfpS;<1PrvfJAKUAb5B|c1hi|aQSB~HN>OFpY@g^tVwrcryr@i^VZ+^?x zFMiS|{&(Zz_e-Dsy1(uC+*1xbX!(=2{>dx8)2_Sa%^Usf?f1C%rN4W``X~JE8@Jzk zuaB=f_K{16v(A6+w(E8`e7@OghadLmA9C>>H=ca$>09h_=Bt0U&5gf3;dKu`X!Bp4 zUEX8a(#L%1h?m@X={n!t|LN=R_SH|{{_`FFbED5!U)*Sm7w*(Pd>pkJ6^>e4JKJw0w-S^~mf4%FeXMXvV`mWiFU;f^2+<4fLe|*?3 zx1aceE8hCH2Oqg~&6+z`{_cp2zVhUQcKQBcSAXQj`(5&|Z=Q7GR$IL5lx@ELx$oV+ z?mj#G$GzY2h_}7?q)%P{luJH%`Xyiaz^UK*(wgV~$Bkb+?!S(I^zvJO_}ORw>(@W^ z=DVNqydNEN_!%F4){V^{?z{cB?^^x&({DfOj4yosfbZS@zBOmR;-lZ%_o4Ut*g4gg z9&zzckJ_QU&n;UVdip0e+xf_24|>Wz#~e6(;A_|Iy5+0ybI6AGYj1sQdES!ae*D;r ze>S`E^74|m{^j%&UcJ#~xBli0U%UR0!+yNqn_qwNejD7n+sj|}pik`g`g6Cv;F-%0 zd%~fIuJhCT-unGtZnFEC8*TA}SDpNTbsoLXvCE&a@xR}-^Ql+A^9^fG*zygBz4fsd zo%VuL|N5>^fAG*tHrscHzy0*c9jg1BcKg@%c+QH0j@)v$uYBc8w;!_eoiE@1>-XAm zgU?-h=enyt_4rSI_Rb4dZoA``ANY#DUw--}tL{Ge?B`x~+65au{b>)l^f&AGkGSQk z2kh{{SDe4{toO9%zwM7Zedg+!4c`0vSA6cAnd?7z<|kiuzy+Iq=6m1&$v+--{^sA^ z`m zyQclfId@%g@-yEx^YJAQS+nXfo4jU=mv6Ck{k}I}z1bPh-s+HF|81W)z4P^tyX)ec zD06)9*PpZXxBK)!I??_6^2S)V-q* zjTe3K`#az7^WXjS)2b6TKJL=)h!fV`iGJw4_$cRp=X?X#U<~3z*BF2-o=N!=h4UZ|9ROxKKlBN9`xEPF5Pg)ZU5s{o4oR^ zANt>=XT9nP4?p^QzxA~Zi6efxbI%?c&0e?jdRPB>v*&HHYU^FM+u+Qb z|9itX9I^Z-FZxzJ2Sr4gd3k z+kg1z@0I)A`NU@T4PQC)#GPM%(;rUX`%O!4eesum{ir=}xuiVduh$*4*`L=t`Ga2{ z-hI)>u7Aac*W2ouU%2r7ckKWAr+)XLr|!RI#hW+%+`W$2`K~=qdg76{y>7pIKJ4+= zz5I!n?Rfp)cRTWT8}E4C$4=Yw-J2DEc-qpBt~&UOCtd!v)3@x-f7s0%JhNT(xJTV{ zcDvIb@a1hjzu9`9JpY5AxzFaOobjyBo^sE--txc|=iUF`e)pz(oOkAx?>_9US8lN3 z`mcS zv(4|f(-|8bzT-Y`UUJ`ueEFy6UGS-Uo^kx0C){`EqrSP`hFjlo=4&4N+IKwsf%n|( z5tsks5C88=TP@#Zr%P5{@Pm#2c_~zB?z4iG0ZoEHz-2cU2ecJw? z-sR0(e{HK158HYFhwb;co7a2NUiv601*yIzJKk$IZ+;RQI zZ-2{0kK5qj&7S(M%_aCa_*HUoblI}EIa5$cW?f#A7Am&ySpd7;N=&6{0%?fd4q4h z{8N{mf4{%nc*Wc9zHH;CZu7P~Uh~0seCEjic;(JlKmU1e`OGGN_~OG){_=aDywzLJ z`^V2VT(a%6{_XQmy!L<>e*2(TJ>&MjAN+~)-}(I$e|7E)e|F(Ze{k2YpYqoW-g%E( zZanU9SN-(|-+b03A368#-Jh_>72RuJ{J-1Za_(oYddH2g{oIy^Z2y^KE`8zBe|+UH z$DjVp6Hj=_s~+&7`~SzQe)RKm_x|cFzklxY4}9fDcl`a5-<|)B%Wk^uLw6i_^Rk<6 zY##Z=M?UZ!t4~^W%f5RZbIh(gT=eiITYdad-~aIe8=ZH_FPCidu0P)T!)tE+&_6al zR_I{e^pf=#IUA^2Tev@|+DGaLw&|UvT2DR=#=rAN=;NZ{EK5u2*dT zUn|f5?O#53+K(UJ{^I95{QUU4e{q7rDMRd1%zYd6#ALCrMWO3SUZ+zMeY)fZZBrR7#yZl&c`T5g5V zw)!`@m5y8KxRs7u>A01STj{u!PPgJNE+LMoC4c9Xb1!bEx&{FB+F9JbnW6vdu^u>- zGxUG@tTbRDx5B_eBe19v@1Xm0rA6jPkXALfvcx&M5GDC3BJl9n z4lH^SCH*8tN!Gt0m#BX9@2Y0A;>MyEEfz7=Cfa72wvl7euO*8W2zIO}$u$=29+g%O zL^GnFOi?Pq_OvAQqgRstMBTFkX2RSUG2884&T@oO&T@!S&T@=W&T8x8df3uBDzuiv z+zV2Mg@YF-BGDQ=auG`MYwAY}@4!;U@$78kmK61w{!|i2QT=3T_eAWa5qGJ@4Pq|M z*ig)cn=*NdPZgGF7;C|z__l%gax?13$g-luiGH+1NJ3r~IbJy@#w!rAd5Bllhb; z^(js6Q<~(bG}%vS(x1}gKcz{4h}Wg2NQtpFFreX_4*4##a8nz9RdwpLmR5DFXDmB9 z9H1Ywl0Df2`k_B9&Pq;qMQ^mn+ZArIZVPeq$}+u|H(A9qRdkLu%;4kmi{!SohGT7(>^8J`NVM6=2QjSfQlU~ z9bmE7tJv$&pS7!_|LRzV{u|^R6)|D;s6AbGb2NVibhh}I?*|>qQfxt zGqeX{Ccg1IG!G3U4K&w~g z@rX*F!>y&&a1L=t=QkBOK=otx1{wc~UEAVV@yV(fzge;01Szu%4W#Vml)jX;xBVxQ zGWmguJiq!eN^YJE(RU3MMF8r@$ef&e#b={xZ;(e-Kjz=aqgIRQRVVAgPL(<{+TR=7 zH3acXHJFimHpxv*{q@mV-&$B7KSHl4!Bjsi&6@HR^<$P~{t>#BT0N_6hO52xtl3MR zblg1AlTJOW2DlcaGvAoKE;_ou&{HK1t;t=fpE;yBm;a={uj#%?{pfG1rOHXwYxa)R zHQVc&Petj^tg$s;RL#`p)~GhuMm66X(ciPTt=SFHp961O+Y?4yyVA`){k5xP}GUAiZ8{^~fQqpS8Vud=UjZg)gOiJ72oltuJkzDy}7I&&QkAls2j#lCF|9 zc{25rDeL^~w&rXTq|2@+kgl6$+L4)9rPeO#pIN$e#aHWVJ}q53^sDW`A6Xagyk#ys zG!N;r1E$V6LadFCtl39`)Y)AIQg?GxU+UVO{$EIaUgzQUKx;rhtl^)g<#VJ{5p!45gtBW_M>M`+hW`|kgXJu>oCy`f`Q z^ix{W(6pjZYI~L4IzWn5C2hF(tP=EL4vwc3aO6RnjJo_l`N(&@4KF;b?)wB_V=h-_~Tlt;u{_ zllivB=e8#EZB6Fen#{K~nQzOPFTwdZlWuhmtKfa?O@x{E9Vb_= zh3agEdOpj)wI1i4H*tb;J;AjmBYsK6{pxwzzz}A|YG^b9yHx>V3&NbGH9%-5~Y;N1IPDsC5 zf*l7l^k<$<$Ey2$M}PDYf@yoriepx|#hT++u6XIT%Z^*VlID2m>SO4OX5YoW zxa^o?)~sH3=n>m4J9_!Ht5&?^h}CK<+np+Yb0R>ykM(a&CDC=|c0<>x+?Hmue8n-e znW?t_$`!|MyJiKIgU9t%eOsd*&13~UPY)fwZU~9a_d}p6$?6WO--h-{7 z8}l7KpL*tCYYfMHM~{vAp=#>dmXG<4?x&&e7>gJC4wcJVxoYLhSS7ceu9LN6y&Og~!YG#~3# zV&5UNLsnoVJrQDj&rIyMRn_>TmaSZ+Ua+tZM)-Zl?(3Wqdl$Il9dxXYHWt2P zdhR0ZxQC9F>|z}+Rreg;8nQX=%(+a*=Q3eOu%=q?V;$|X@_6n^$9TL!Ouo>W6QYg{ zX4q5VPALQwdM04flRi%}J#oSk-4U~bG-qK)=#!?{B%iVJ@Z;9dGfz7n^^%#bk6L~B z>c{Ij^GTI#hIF)Q%uq#}GTgQB8 z-Lh;EDzL8ls4mtrS_D4f8zE0=XI6u&O}eRA&&J4E#EPDhR;*B1u=Dh3W2|9sO4Dr- zC@Cm_wC8KsAUgDp^(;+E?~hah76s^(K&ss}{g-`KzjR-EeMh-} z{D+-aA7%d`kV%E^TP;p>#46gD>G&|4jSkmDj6ZBle zmIzO-7p7-=? zj5&_93$^6E8Zfe&V-)Mz*aeuPY!@2X1Dd21YuH;hW6x5mT1!!R10G4=y2pB!mW?@8 z!7?@A>a`F?wXDsLQ3xHW&UA*&)iEd_=&1&qr|)NCJ)!h0oG&FkQ6I45k@3BSY$#*P zmr22l8i+tNVn1U>+Hj}6c}+P@&~pn0MAP9idY)z$9n%bg_8Tyb8gh}*{xkxO8fEoz zV$gGodn}bfSWV|cDAvabn*n`p3#LzhAvP!5GU$QH5g6zajJ*Mqr|$-1J$M>E);>tF za0~W9AJu2{>?H4ep&87q1uGE}A)~I64{AneI>oK=JfN1sz!tW*?kqNUyRMetqV_jm zqlB}@{jJ0_re)9=y{a=E%OLClT$L`v6YBvr#uh|K*~D53embxqx~Ytw9Sg#>gTk4C z1<`ecGTI+&L8RcS0}G;S8pV3H`oI;D*n)7`qhL-QSP=b%F)h3Lz-vbOASY8TSdd;N z6tNyWeHd#&q`(n#*V1N)$xiuF9v z2X{_#Hs67L(DzznS_XYE_JL;@N)7CT#%siSKz*>)Ia2naks{6>?1OG9qi4rHFvujF z8Q6yq{t@*k7GRQ`nG`$qU>|f-v6)$Y(1l$nt5yDDf`&vL@4-HVm0-L%*_K^>;58$p zfovZ-un!uW7#q8%4CMgS+1X1Bs0{R>2m26G6{GE2SY}cmq}Ztk z`=FbO$<(fzg}*9&U`#|fC$JCt3u9UaeK7WcXBhSX_CeP%i1mQ0Vqs57sY&OF1K0=M zR7TH^eVCNd^Y#+h2hASMXn(42(F~-K;>iIuQ8g9onV+Snvo3}wuz_H<>ol0%bEjvK z>Dco{M^bqSYEK=G9X_L%R!D&cTvT-w5*vV3NLzhSE2I`cpe_TLKK+GJExXI5PiDfF zUDMZV2wkjYP{iJ1rIU&%1+s&?$+)Rl&l71)=fuMeLzV$do`!diY1!Sryv0a2v^k$K zGYzEIyJo!)t9QhVUvKM!B&8<>%Y(bkxT)A2y>&B}$<#9sT96^mETzj{`ykfb`6+(*}gcyN_r<%*or_2BesE4M?wH zm9YVMQy(exR)`vlS=fvkz&XBWTO1~($gL376|@;R(VBWj6G>Y1iHSfp`lJ=Y%%Z@am64A1EX`>G6NZ4Im_!fnAFhf@kA1 z8ku&qLU3LbxUE%Fu_;-7u)HAUnGB59JCG;}SS1%(yWfd~Hr+ltCq{OsSE&_3XR0d< z(oEe)h;!0=I9w;taV>;V($aQ^ZIA&U_dLU}2QcuOa24wTb(_)aBcvvT;eGTx{&Pe{4OvRM6K+k#+?(K{pla+0Kmt zcWmz_1&A$MQZwCrkvAwu!6LYn{} zp*{&~@-)G0lBCq6@E_o9y#`8+nVW-8;^7K&0-KP88RDEAuwgV7?xa{4@NLBC85#S) zoMf8-0JmO$VT`mu6O2vZ83r~10B(H}Zs}5B=*?+loX|-TV+~PP5;kh>9L!0!2{ptCNu;lB+0_I?K<}A&9!d@31pUPk>j8O} zA;xhSL-{a!J@QBT43GY6@?{y$TL28dPePn<-JJX{x`QR71VFT2w=`nvy)AI6f-pv< z1wsWR8h;_yGUG>kE&;$g&hw&%7Z*2L0MxP1gLn3$;ho_rdI69*ZYftp+6=7)5rM@@ z;uSsp9BEg`R8CJ5rQ?_+_=b|Qcnea713ff-j%k1J^Whi zEdcSc-h@$2)X?dk>vk9s=u0Dd;mR017EfRm0MOiP$YiV|R3yfS>i(jJPRhst9@Zy; zv6EGvMtnTlF#2l2=O%%#W|eIzWo1DpxYtEqWq=pyByg)gO!Ed&QiT&*M` ztyYU~=m4eIYY=6IevUmDl@i4kjtr7WU8|t>r6R3I)>>eq2#BpdiNuwpZ%?HbTS37L z{w9l}MlqHy;g%^3l0wlA~0|)nG!NG-;Zvyy_n~H5VNk(hQsC8i2 zlMqZ#L#M_eZq%gvh#m}565u@1&}qEhb0w6(AOS$JPXd@F>D!Qbku?+mk9`tai_&MH za60BGD6dF33@IiBSYMxnQcu>$iAiNpZqY-)m4r$Q>odVfFZTMt=}wZ6A~*~-s58c# z(0{f1(tov>0@VeScb|t>?#JSl3n>Z)Xd5>bGg)@I9aJw5H*^>ST+Jj=y=J-X%aO`q z@Wd8BKIp+1=3%P)v6$*oimw4P$xX$iFUe>vnJfTT_IU{Ep3BFiO;#yg>>w;8iJ+cn zs17bUf|aq;1wtT`IAclrb~`V!K>|o+pM+GR!?5LcQvqd}%rHvIFybzyOrDpOLf}L% zn7UWfNff(XV+X&^LJ6!8y^#tnr!IqpHJ*Uf7kiD-3aOKgs4WPy6gJ8;#w5{y&H26z zf-ev~8@{O?y{mOl)6p2P6k$I~{tY7e=ZKNo=IvmYy27xb%gyxnVYQ18i2y5(Gp&_hG>{(W6jn~c{T3Nsy zT9S?=WID`4n(6sjof)$Q=)d-G9L{~|jdIuQCCeU}qC7+saxRq3g)H6c7zf9vOyuzN zbpVaUN)P%jywWPESimfJ=iDoIe6Kvyaa|4iFW)S6=2eZ3+0evO=8<*AC3nUZcl_7^ zL7~k^xezl!)pZz8^=I|>e780W;0zv6Y%8)tb1kDG9tSXz3B(MTKmKB@533;dom&d9%}j!p0ed+l2_AA~ zxFN>$uz*0#5l{rZ&}QPVNTGo@%#k}}u+L##W|tlmG@E zlIVSOQ}*F0DK|oKNl^me_J$yQNhcypQ_l?K5f&Pg~BDghfh zBv}~Joa~VVY~T{0p)7=K4bXOdhDRkx&CT^#bz(iRl^mEgWK@g+17?X9-CC9aH|LQ= zN35;ozz+|Y2*ifsC~QFe4|yz&A;!`G1rm<5NP>0t*Wy!>Vqd^74oU8YrTq<# ztK;#CTuU2x5bclkCB&JP5Yh~JoPi<682}9xuEa}#`*2e+4V}#0QqYx`Gp`d(1V5!b z+GsI4cTnXd2W0nMRZ+;nA%7SF1bYN(#SM9sg24(d=?jI6=Ms>W+|)RsI@y#dAuI`1 zMIy@hMHH%W&k%KI-P9p#w zueeJ&mq`fK%@2npt3nd091Q@*cSwTtQK(!JReOuLP^H6106-2&vc*)W+S9U&V)Xtr z!gjX5(dVe9!m(D8bRh^;t_fR0VZ|Yd;rE0(-HCCbN{IuY_=Y4Nej-$-)-{h;)>OSQ zC~yugk(+OKgE z(=&2*>(miDj$mStst7Du=;ZKH%boP!PqVpH?B;MBy#x1f}`K|M!$jwo@VFx`UFy96GuEL5Y=QK7F`X&UJdwO()J>=zn>-YT9CW+U5%6|(PBo1L zf^7;I+#!$VFmRFS5!+M&P=l@kmcngC=VbS(Lqp&J%PM6QFDg~{mTX9}70f;bscOXy zr{*3f4oT=e?o<1Gb23s^pxv-*aQ{hc{!~|;jmqeJF#s_(Bq~+hsH)xQx(d3gdkLoo z7aw{Vq7AcEcjjfz*LkJMb@2&*&<~);hvY4SWWMzTr~{o@gdM;{@>mH2qlCw7Iw?H` z5Gl76m7(2qPO0y~TuTV1j1?yyN&z@@NFuv&Z*Yz0F_V|lNGNAGB;o4w?OMX1K&8eZ z59dFOpS6^d05X!>8n@(5Ji<`)8I~FC97gR+7Q!k@%t8Q4m!9AoXCWNkhmlCIu>hny zBmwHUzz$4(qS|6It+20Q*KnVmhsqzucP$0HQ1x-hs~VlrwG1OE;Pfkrt~JKn)h%9(aDl6&Juu}Lmr-fU~upV zlPTdNOTY#WNm%uKXDvlC0HEY)jMFX0ZgI_U(k&eY(0|!6Pu5@>g|kzOyDosK4oU8Z zq+4>l2sr5>uMYRXfcP;BECmEmYf?XF8jaR)fyZ|(xZ?`Yllt}3Md?~_#}z>OGwNLYHkim2(+hL zqfMsZjw^s_4oO`1e7hFhaRvBOmf$$ua_kn@GAG?Kc8f9YV!UO(74eA`ph1Tu0YuU* z(QZ|Mw;GbjYLv2rub$XrG2T)rKHnWzP&snQ1Fa9EyH@bPplbwKCSh&!oOLCfnN)}z z)zcWITg*|=K7yBt?3O``4UA_Kb<1qQsBVGXN>Voj-I4+16~c4#0OUgqKn`|G!fsZ8 zTckI>6Zwg^z+>%}dSNrvEjSv;tFWFiYsnoWVpU6UoNhUGi-Gf`TgGn9U2>f>%4ob* z6>vV6ETk{#mTb46ChL%_53svFNwS%(I?d%5x+tDBw=ewO4%ut-XMSIU21#nfW6eY5>`yA z^PRc$3TFkdYU*5>j#%f8rWu9Nn#TBFQZQ3*-b_QZJNEP{78jN7aS`c^>MJ@dNz-^) zLQQjTSZJV`HjQZkBMuCtS1v0++EVA4Hf?<8Qg{UTVd^~7rj74h3Xq^wD|N2SKy*nb z{>%Y_o8{U^X_~cZrj+7j+fQwpJs6H@8sNmKRb@Y;!xA-3wrKzrr`J0&ZJGnTolH)& zX|)tT04A3@&$MadJC|HHAdRW>Oq({obIElBbeB3GZ_~I^yosC`YE7EPpl9_#`!Olk zvxR}8nuaz__m!<_ESbQjL4{=+Xr@imMehm2nT%9xDOv%r5_O(w)5do$xo*HJQ|FmB zZFJ|-JB$@TwW;&*HqCiAz$}-tXp@dR9$_}K(QiZzj_WdUnZ;32M#9G2OYoC2i}V6gZ`Uf z9PqY@X+LeZ2gkC|m-JBp^&wMlD|oqu7A4buGdh2S{cfbl4DjC6`FJa44+C`$z)u8- z-cg4~ahnAs1scRSn}t$lF$4<;>;q~#rKDbhIscyTM& zln@vW$&8PS2mp(b#S@CaRVn^LOxTlR0fX}-py78CX;g6^Z2ESnTKGiqY}?KOpnLf5Hfv`HNNhJ>B20AOso8zBPvP2;?^WtQ>q z6(BXuSH?B2cZW%nn1?!W=3>Sc+^JN6#iw3UQ8e35 z`b8D%bBaoTuwfl9*rJ=!3d($&!Ng?4c9ecmJ29(JdfWK6r~<|f$t`7ze1#fof~3oM zfD=>SsnE~r6Z0|5yqL%k%*(qyOV)Pw=QZ7nLD+>BK)48ot3jGqD&UdlC3>X_K;ZN| zY-$hs^U`Kzgk_U*P{97uyi!(mX{q8Z`bF0rFwQ(!FM$8jyiz;Uo0o-`CJmdE-U7;+ z`c5VG(Rsh|mwo<#nm#N<0BX**6!VREP z>N^!;I2t>hvKh0iv1Y~TNO?|;1ps+5o5XAT0+@~@u2j+~JHV=`@6?v{`nGp7$%U6r zoB`ZSeW!Nn9Kz>Q`)OQ0y*XmUN!(ljxZ7xQY*)=;F0`8?6K%?rnN?J0bTX8_f|AI_ z_>Ak<4cnOqs9b{`05j**NNncKxPJ9FT2X?%5AP08ODT_GV>yS}X^khfy||fh)!}hs zk_9S;aLj}a1%aL;Su$ag4O4_TJqj^#rCNHHP|y!hqs@0mEPdychOsee*fyrbNwUIR zDY1>sq>ar0H^r72n4ndz_Fh8)R%$#II8Ga% z+EO#7Aor;O+g!}%F%{_dr^!TMu2F145KseZ&oma(9UBrmpnWssaAE+grQb>g7@jX+ z4uI^4abiLgPy^nSI!{?4d1Bhz`kSH#3?;RliuGl6;Dw`Y%@YlKacfPH_9#_~EseFK zjGMFyZS6QO7h}2v-{Mlt~D>w^1A*dfWmChhnvduuFo?#d*na^V+*3%OeyNv(Ym6My&c6 zRmh2JI3=dGQhMmi)Wq3Ie5AhXU1>FlH9~iA_CHTv;S< z;eis9c=kCarq?dm1s>co$$XhK&cq(G#S8<(NL@uullt&baIr?%D&71h%qz-~?rbL~ zk8wFl&IwU(+*WK2_gl&bHVpmenevF0e)txB-$Pd)vtnlZomU@q+^VBFn%Z+_dlOym zv-+j`9<%J|8L|Z`%$oiK{kr{!U}+E{NLOu{vYMXK#$_d>)HU3y6?7k;=v$VRPIA_c ztRSPHpgl2OU$4d*9wGa#5nx9_eWGt!R`y6|E$9_EKJxpC@%pkFYs-Ywf*K)9l+7mk zmSts4+2YFz@rz{E665t{6*<;|Xj*{N)rjSz$ScveEGsqQwPUZ~&Ywh;l9dfYnPO$_ ztG4hn#^jJE;r*mPXvI^1qoo?!OP6F-6q(@tg5mOd7;$?k-453XhvUX#&c*ss8mC$y zGkdOi9n1`&UHp|;<0dH~Nx5y?!*GAsEM2i|`HD5i&K$h;(W{rQAkY>uSIGA~-}hDX za$*R}ERs-jZv#1a^TeVU*Sg<{$_tAp7}70njbOeai8+@=JD2emMcXcvXn~bhWbzjZ zO}3Z=XbiTgkfLqGh;d{2Dmj-S7vt^=FrPS7lb%Pd5vEoo zAx%?LGW9lOfb`xEObOJ=B}BHqB>qB(IlW9@c-Qe9VH;wJAa_Ve_ z)CaA+^nuqYP+TMz6q&S&!og1_9ElW);bA{F7MuKJOS;?w9&>oM0JTtQ{>l8oY)J-2 zn#h6YM^YQ36bt6vp_(uaJ!MTiQ_38R5vEiXlS=G2spwOUSfL_Ghq3z&MXNP)tY{a? zyCW2-NU{uk(T?>}>N(3`vq6zuTGwPKFRA2&OE5|$7s|UM*s;i@h7?T37^9LD6{S>C zI?Y4OBKJ4SlsJz$P;O(7R`7TY5q(9H5hUt6i(sU_FPL{n1Z&>!OVT|KOt zTDNonP)Y|uh}tZYya`$QIl07wd3QwV7TW&Bv{KC7EqjOUtn%(ml^6m&GE|O#sUvApCj<6G|npVO~NL8>bxWVQs0vT1rIoJ4 z5V>0<9|DngO-?ScVBWpQ+&xKY6}>w>uP!z2VH^*4J1@rER$1XByM1}J%NIYASYEQPDzqcf^txNlJ}xC&p$0s{B?$C8df{4HR1@(WboE)Rav9 z7k$m1o`WfApold6mikKmx@Gy7g*usslFxLcn=-N9y4lAzlCZBjedbc90|2Q+Qv;QS zX$tE0BwPB7)*rcR7RtLfP`j9Xa4L5ey*oQQa^Y;()dw9bs}EXv>4QvGtC0jzWYVb$ z=f#4AwG*PU20`N7SZv)UThf-v*B+Rwp!%m04OH%>`74(fYutKwhkr-k%5p&ql)E>G z2re?YU`31z28nr{z6p~GRW(q0nuL@D0vYd)qP5}X+Vt)Xk{*gos$0S2q7i{pEks2P zQU|!Pe3i5wXq4O*$h$YlOeiv0YDJ8t1}dq_gC)GXRMDz|ve5*mNO`e|DX~>FwJBjD zTVP5GJWET`14UCZVWEv#w}r~x8zf#7dC&5Y9LFXKP5R8GNe2K@S*4~x$Yb(RBU$=6 zhJ3-iJC>s=l5}j*yR)-XF5F`1EXA>4<)we(bqW+0=^sUs;^oD54$&*_-5UY2-5{T! z7)=2yoVS8#W;Q6sfZM~OkEQw)F4c#Jw6=5i200!@k_+W8injkFTu_s~32THimj>w) zMUud1_Zx^dO`dWAiwkrz-(a!vB9jPMAmPIBBvKUQ*Yy~JxgJrR~vDoCNTXO2Z2p+5A^x(3r z@fb`=+N#}>4quhpwjkP3rgWilcaNx+$>1y;K4U!OYSTAit#sx>nZ=SN>#sO^xmqj| zlJYmPb(2M#b$`52-reJBWfD{ieqm~iwUeSEvKk;aW$*LlWBmYnL7ZdHolsNBe(JZ*MCKoR% zbEvOzQ_`i+T)K1s&d@v&*zf_Zn3x0NhkAm;Ao#YAIgl`l8% z+|dV{&GR}1-W?glWs;eSt6y?~>=C=RlcF-DYj9&R)w5f&)MR5$1&GCBgJKN0k$%Kq zi8XGvWa+#EMr~)gpoQ}8$T%yL6j*;zwEZ8mDCwK9PC9czhESQLQp=*%nn?;d%1bSj zcW(e^QYIO*zG%mKsZNTD8UWdpNm{imH|v2$$!(#$J2KA7%m=?phi01a66wpLPC6E8 z;XyL)FSgsKro>4Ucv@kifE<=GN%0ofZSua=m~~sQlX;|*m6?p^ax~+)OP{&)=>VXo z03dKt$gJWa#g=!{ROW)PR+k0t{1fpK$m#z+g}n{S)86(g!|rqz@ctsqu=5c#TIKv&jP{yLo4w zqa~vJYs0AcggPZx9}N1?FbsY1)Oc~itwooITx!Cf9L3lb9ZN|ijh7V2?YX22+eHrlFckMRz&0pg>6IXTqZf&b5uku zod+fYS4HZsPLfPXM458v{f=bOu(&1n7+XrK?e!g^_^#sq1dG2v##sFOK^ zr3Epn4U*c*M25D<F+(tsn)}KNk2#oGi%9!2$!is*#`6nT1dwKBCPA@` zJz|AY6V6Fm1pRVjxQki@f|W`3p)55qifIwTUM3;z-VTkuP=!(x4>Isq zr1EYpVt&gce{rgh?oQ(@+Si#DG3;fMStv`^o*aVhYq8FGnMu7XW7IoOY=S>;5jx7P zjZ#RLd&h$gw=qJY%Ov+s6r212SBvm;wwJMi^Mj`)`dJ(AvQ47s+VUiMiPg~#&(qh4 z204pmCO5B)ar3-Y8xgFi`fnkg+G|G$S6V!H;8DedIN3BHMt(2J7g39)=F21(%QG2F zY8eyGNj2J91Ynj)vesm3{6LrS>Uz+EVnboSGD#n_itX?QNwdVfrNvXRGLx!R#;97J zMhL-Bi{MIbZInhZXU>RiLbF0shhX6{$sQENCUcxxEZANqpKbEA%^@2lLdZgjh7hAy zCV5B`ZFAW&Jm^r{5OZ240p_yU#B-MxalmCJ3#p8;kUVXZ!XZ3)=GI1O8`Ht8w#gd_ z@uX#v^(Ko=4z;l2dzmDQ_}Vr)VJQSGO$+bTQqelq+BmVf#|z9W2+THO+sgD?UAyWs zf+g5CJ)}^R5eLd&i49zG+H9YdXVyZb5BA1`msmM%=1v4t!!vx21!CP#cBxYak51rh zzqVu&r}?U1ep6e0&?-qEELqct#~)JD;b7V=^kZ_?twNyxZrKEqHUQ;Ybay12JBq8 zgKe=aEH@TYm&r4w?xd+3o##w_;`EtPQv{2m)x&9fYw?G0rxptmm&r$}Jk1)v0MdC3 zR`o5DICj7D*bNW(HsOY+^`e&~^J1`rLf40 z4)torlyKsxz-TeyNhz5@K(QJruflKTstxht38SxKFnW}l6gVL)h8r6rwaSIj^O!?N zhqxI2O002NYVz3+;-IP|9vXLArE&3mWj)#K_E{H{nskPNxg<9ho0#2c6~iz&?%^?q zQp5VG{FPYavee|GAH?%i8j=}n+n1VlJY(#Wc+G`{BC8}8dMdVQ$V0WBszUe%;N)qR9jY5wYkAnC7`K#1 z$?~C8-PV7}V59&syKQq4KmcFL*IX%wfmv=(wKhmS9nV@spq zv9??ptwoA*r4z}R63ua}T{)nE&^&NqY76Zr^Ds@}CqX6tj*!E4c*Daz#)djIA+F`+ zRM}t44$%@-@~&puxZXe3K8ZV~Lm*C-iR!JQs9uztkoR_2WrSOc$;}*TRSZ!!Gn+h1 z1IOAOmUgQ$VZBup){8R}a@r1Y0o+>t%yc*tC9m}BjV`3-ijh$&cybt}x9ilO+B<|Il7-NvN>=F|ba-M*sglo$_$xNelM*W?L;PUwQcR5q zn<|M3o|q_{yqINmh_IKdDI+>YmSrvojF^9{F2%AcOCDypf z7Ai(&8|%gM3-$um{HQVkzf~0QYv-oH0g|J~GC|x}Y+@6sxp-e5b0{?|J5`Ov`=Zoj zyl;o4$oMO3B=^)J#MpHV}>hMy$(yhg&Cb|Pgp#^&z)37QN z^ISzS&$zH7{6Qf(1cc9UkFnX$v9NLygII6X zP(g&SbOdtxA?Sv$nQRLKV# zWU=W926haO#Hut>Ux=7_SJBy|t!>Uj6x1JX{Hshbb;VfYQC35^i0lx}!>z?Ow&)II zEOm!yo+^3z=V_mF0+`UgIci~m%TVucr#8QOYdZNm!j(sd(4lJV`6E4(Jl$dR^r~!o zJy3-HN^FTH+sJ)aku!C5R?ca%`e2XRE$z!hqV!J|x6R>!`WE|U^}(Lhv*OX;@Hz#X z2)Q&>lCNzKZWu*wY$nTx+Fs=I8sz3wNq)C@Uc>SZ1p(M@KH`b3-}Df?;&LHI7JQ;b z0%r*Y{U9fhzZ>hv=m{Kxn**qzZRD3$N#O5Xhu{tnINZ~gg{0Fr`LzvxUy1#3%Px`NSf)rrNwEV5C>dQDZ52w{z?%Y!g-3Jj8mdCP=ASA3N_N7Mv+ zMLGocU`S&j(3M-(uHw46!NfciQYHktiXw1fV$vZv)>z@jV%j{}DQ*}e7rgI0EKd?( z>)C)-pjNGE?DmL~~po)~UMR2%cg_|;&|uoOv^3EHik8s91NCS|8s!G&9kE!rGY zlT#rN6O#nRPaD_KrInjDo@9D>s-XZY_g1OSECXIS0Nj)Sg*>%K01LM^PJr5v^Bj55 zq3c65RITwXvBpvDYo{P|YHC7y*CXzSTZ{ERT|Stan3(if1gA;@f2NItZkU9^Of}RE z$dBt}y=Py5vEv~yh|;q>J(jGglh|rI$J#+v(~IQd4N{LKYwAo0avg;rkDwa-4L>=9??>D65ea)Slc46>VB3=Vn&lF#G*aES;?)9S-#pWF3f`t)gHlY{FO0{ zqupR&Iq8NBXYM_~p7uwhdV%cD5HTs@)oVuGaX_Fx*uUYeuC!GDjjyF0!uacCU0zR1 zox{U~mdeN8u-fv4EBuON2JsNMPL^!8st&0#&s@+4Zx<^m##YLgkG4Q#cClmy5ieFJ z;jsHH)t5xITe_rXOfW6He-g9rp{tKsF|+;7tB*Qv)zN$@vFFV8=45!E)i2%mm}N)L zm>Z4hKhUq+fAE#5M+{n>SrE9k{8_PFCa8gA@eqT?jm1_<6xO65@LCWSTuIXt0ePAg zg(HKoBpZsLwOTipFD#p~Exxc22Ulkzoa-pU8H6R}?g%I2#`1-wW4*Pq4H0BjCvU|( zo8?@NC2YEM8i2UII(^F}*{sPe*ILjlc$A(^XLNCyno_&iZ??>Ig=tI}eXx*oqk8IZ zYYmaY1a%<7q^8+EZd#B7}R<6@ut)(lLEnl(b*qMW;k5nrk zu^^T0dxR_2`ldNHbWh6}Mm@$eOX$5G0d{o~M{a|T+Ch+0xeRMTfzQz+gp|J$o0_?b z!Bv^y#7C{lut2MV0M$B)hW1xw3T8^!9tn8ZBRH^5g5YJr&1I=2btcEOFzSqO&|2e4 zVr%XTZgjq_O4$aH8)6pgWXbNSI%}(Dj+qz?6E+Tfjyj3pmsiDR*<;k1Jm3PY3VMem z-r8T4(Mi07B<-<;T%AP!Pgg}JduCN+D0Yt}-C!5ap*0jd z=C$s#5kFjK!qV#~EFFU#DMLhvEw>gkv6Jn@AbY!=tRX_5jS$;9$!w5U#m0zZj2sc8 z7G^tP?Z7${QeQ_Q^|&fhDvCsQZY{Pdvf%7S9V55}^Vx{ut&?zg&ki`C_*AeXrKJdc zt&@29sX9-+Qo(}`&%F>=T_@qm;;Qfj$9ji_^4W;mu9HZ5e^thZpi=&eFx^_~e@vYx ztHP`ZV`TK8g;l}R$RztiUKLy4VANh&D4&fW@LD^gm|R4k&7PASGh1Z!K_9TH4_c|| zgUl}JkzGjE=7rP&^2MvFu=-WD?kgbE~lPnAf_`#;TEZCU>BYatFXWDD-?F zI4l=fCsFVIvQ150!o<#j%f}H)sS_4};rYfCd%EG>Af4$Aq`orJy~om#b&_QxD^O0f zzF^@+i_vm)%$6dc!v8SBUv>PP_br*#sM>kDq0nx_OO zT|OZUy-p%)CwlEdYkAP2Bf~nFwf;(M)5xom6D=>;kpLp->m*IVUzO>uPpyiS!ywAN z9?d+cUFHD~T38itr=~C;@~UKo;tLgCAS0tr5r8S*&fFzfC6W-hwb+K4I5&qT zRIswD14CQBkC#yYjkO>$1*6Aet#y(wWKAvZ*qob+1&imfu5g{n9;wH(M=B}Y#yYdy zT5RP+!AQENVbYGestFfB0AbS^5z-1C^>hZ*yN{X_PSi`Nw1UE56OcOH4MRKY89*H$|k`5*B6?@)2YOgF* zJcnGWTARI?T*P?JQXbj7DznVSM}4q?olLjtk*V5bvW4pLY@tes@&{xKacj}p8(0Pd zL0Kty%xgWKLoQOI5vj4EqmgTziv1}gCj`O+k~O%sSnqZ_H4X==;6VrJ(SSrJ{z|NI zyPa@VEaYR%c3LQ(Js^#$$s{;6%#j&$22%-9_J9N@ZY^JMS=s&q`RoDdQ%$m9zpu`t z@xPUjAPo2_c9SG;P1SjNTuth1Gjh1G9FUvUXr@>Gs^|%hJsDddpFJS+t4UIayj5X3 z)EITHg~Vw(wv;YSeZb!2+p;tZzU*821>nRg*2}JkLSWwZ;k!A@aeRB#Td8xtuV0 z!TdT>0GlMu%U5~r8Ah#~kWvoF18b76aL9toxs+Nc=*EBytR|Df){LjH)k4-cAcc)v z8>P-n$kPi}@Sp=TI3R_sNfHmmRhbaiMtP8h^6SW2Y&6C`CKpegoyz8kSibe)mYE6=*Ca+44dsr~Pj)lwEVZ~NO^6TsmmGfqctUj0{Qr1xQ zPb^3OaA`oIc%unzvHpFn7#)MxQc8&=ye3V;<6OLPNq9VFwN=M#r-htd#q{Swa*Vc^ZwKY=Khr~8+Ew*eE zb=G7>hI`X$+b|Km1KDcO31#PFjmxWIJoL;fLI5%8 zSgon}qL<@uQ{Yck9Mi=P)dzd4z>y3MNsb0P#2s+6u>qL7KXeRVrEMF?R#_&drO z3cq7>E!~bdoDzOTKw%6>2jcn17T<2ehO0^Q(zCq7G#CNj{FQNyPtO4hvnKwM4@jPC zlFU3WvW~vXgR4lVVS@Bw6_sNYeh0)a9jYN^sYx;bO(o98);w3`qj>6q^x^5*CJFcV z1jL-hQCooyri96(faI+J0+Pxmo7pO}14iEk4$Nz#*NN}^BRz{DgM zh2(`MN%1pPg&K$3SMZRf)1L(|!89PzsL3S1HJ0uomS6&5Ne;yegp%AhSy*$OaV~s%CoW-jg-U+LyH;EFfy~n#Js)^(MQkb=RDMdxfzOB{w^!9$izrEnyxjNQTn9LRNQl5`|bx1CHhq1)0012Q0*v8gG^ zN}o0uWs!5!!NW0*rN1?}C^nSxH;%X{3sjb1zy~RsO!`~nyi1W-6zTE;&n24VBP_l~ zjCKvu89g4jG?^5$Ci(ylm|CeO*nq4QZY{QtcVBt*i}i_&D{|6KeWp51&Gy{sS#&P6 z=ZlVU#}Hj%kuF)y%(lF*h}0F>eq_C7T8$ z&@`EhGk2{L+e0c%G$4Vd$$V|6v09jpGo=zZ1Cl_vwRxy06R2br)#$T?iXx$-$>gr( zEP>>2k+{%ga@TTtC$BXX(zADlooiK8GNQ-|X)^h3IU|&;C=yVvrKaXXu zVcIfz2x`=-EDVN`h7M10@`z$`5mSF#4#wnoq-*wqvylmF16I^%(gnLF7pV=LF7v@9 zb;#Q*xVOMU2aSg7$EN2QOot1V2s?#B2P9l5CE6q@2IeVYoFY>UyqQtkfWc`s|6u&g zTAS3QL)tQom8f^P^Jp{Q@XF~ujFqT&I0(L5$p^4dr*e7^?=GnK z!u3CGCO0mp_wa&&dIxjSCRteXpL-boQ14)8+a$qk{=J9c5A_Z%q|GGP%T zCYe_ApF6qFX?P^(PgQs_Nb&(|*CvT(^BfjmO#;@G8iUnqFAhPZZ04c68uSF2J;Y&wtk{smi5GI0++MiN#h5+<7 z$%UKBPg@%+KM6)u%p(4_O}^nKi_JpQyd}Y$R_~?grjs0)&CggF)cVh1L-BYclbhB? zxoNlyr4$w!2;5q1s&K#`xiO{xFYh8#o z4?47+$V=d_#N=kx&wX00ZB-2GlP~hgyGgdMNRVkWAHr&54`HD~OKBcL^IM(b#3bu2>-f&4 z=n3CrXf-WlQ974`C&bya7-OAJbc(r1#`){j(u$)sO=*z4%E&2blUy!QgIL^wJ;v+A zR-5qHRCX7_0rn|sPfR8vAI>7*u+@~8SZBV*=!ixR*-%}jhz;@nZIXB-rtZwr38aYF z{5E;{>rX6_E8@h&j2nMNz?2rVh~ICMM3&$+04MoLh^jv=waY(4vag5)4}L-6@(QUQQ=jP}TytEGRS6aP=^hOj0}i z)f>Gj6^b^@ls)B@TsR_;+f3$5%dbj|F&hHbwU|XDGPgEvg{QG9t*}j*_-Tt^6%caX zCfP{x3d<=U;*{Dh*}RRZ3Q@7s1cbQjg~1QW5gyvtP8rafV=igjz&)JLOxALSiLG8r2= za~Fbu!b9RE`7{%?a*HzYf+;7;{1Np*Txg05P}C|~i-}rPA{Kb4pm<50zo@EGRq-VUpk?rqz@8fZ(p8@X(P-f`qplm>w`{Wg?FmR3PWtsWdh-IdY2p^ z!h5*2m{qpIZ=Dx^3KkhT0Umu2lNTQBE=i)Ww%=h-P}{odU|{wsEz4KfbC zMB8_o8!#%%RA}>$YYPiRkgsu96?cs@qT90t4E)#IyF&KM{I~Cs2p{aRx zCAGj3)Ro69%nU-HE)y!>F{pgZ%p}xzfmp3hqqt*>hR!mlcPS69VB>U|nDdT-(xc`s zxoSk=aBH!-PdKdZvFvdKbg4qpOjC`cx9wO`y6=e0dkcmwUZSfdT^9 zxV4drH@&eS5$ohoR=g>{e{RLA(efm*&i>w?jwPjdBhJ=kki92NDT%8+MN*@R33Cnw zHg_CmX-R<@Y##Vwgavj<6tyQbYZ1iLUMMOmfPko6HK=V8KQGT!k2&0tes#;#!Q8ZQ zz16iDE=-Y2;sEn?v--elN|bkfghsgoN1yb;S_?x(QGa89hs95S!=qIn>rb$;<|tbJEWjrVIcAd>TE5*ygc>a~F!oQ}p#|c4$CZxxi|)?J29= zMdO)zvPzM(QS){r9U*}MXp%4xqqk6=+mwF|+s42z38bH+Ja?y2=yQeNcDA}8Oiwm$ zYSJy?v&7$#p%nI#jN74zM`#CsN50jz)oXM+>a`=G9sC_JWvFaAsM}F-b=VI6j*3u) z-?6}a-A*COr^4Tnj>Hhd$SV?4M{C|X+ccSM+Vt{)EN*)K%DBd-PLvwg#>P`ZI#Pj+ z)Ftump38Ai@1dUty&6RMm#8yzs}inJiTWU~5$J<@2Qh31*HOH=Lr`Rw#O0eh$Q=_o z*h{eteUn9}rWh7x@)|m(6wHy2prpmwdy=NmF_e%e=`p)Xv;>}{rR)qVg7WNQN-ay; zdNMp7N9-OiPORsa2sPx!ViTJvln&1A)|D+V;#xZ$ zpv2ntjHKP2Vq9+jksXkb!gpvl^zX+y7bnIsRj^`+{p>W5Ki0NCv8hrdtiN zPH)sP8X;xsh}P{gA8qLzc0$6`N_3L~tKM>Jv8hjQg&dJnAfgYerumz5D`XW{-3oDN zDTI`WjOsFpDH+Qz5mO4RK-^^#Q*wG2lT!>Igc9aOfzaeGNjjLfh6*Ljsdo&WGKnW$ zl-7aSh7b-=4Scu;NWMKYmx}V8$7GYZDr&OqxQYS_vCHJPYZ%eE|+$E_I^H%`z zbkkE&!HAZKG4C`DBW6kFKSIHZmWVO$lAH&xcP6BaG2zlF9o^f3iY9qGbEqgEJ<3+p z916r#v_zMrE&C02#)(m-DO7Kc0Sf=4aG8?3{N zF9F6enNP8}W0@E#`BtP9a`F<9(p?g6?=OK-vh=Y~DI~cig3`MrHE6C~z2L*-_^xIzyt6Q*KRE+LhtE)fpSt<7f%v^f-gfercNOMqvCnJ=#7 zEP>>X5tZI$a&x*UI|d>~36WnSE}UDN&l1cXFyX9*-fh-FH<eLdG7H z{2&7P`%HpRA0-HZAC%zkC6?CY*7A1&k6O-&?9oni7a&!l&*dqNUjl`)@o$t%WHa=c zPiFKE+h$@0D(AQ^pcVeh`TdeI}cykFt4i7f5~( zi4WY`e3l>*4Vnvp_%48Gu+MzLBf}R+YN^Mv6h6tK*W2WOHj(#DU#Dfl0u*PC`KQ9mI9A(Ysp(7wwPO+&k`^h zMp^<}p(wgjJi>?;X>1tsHKsl)qHA;ui8nW8>Th^_^ntA^eK3Syb5)^!hrP%l1hM!4e`9(#yPp2W5}u5Ljl8iZ z5Xr*a*kjSDKKb^BXS_7WY?Sd*?@pY~fI0~vUwjirgB7=sJ9nqnaC=_rLU@x|`CW93e{)H{5QaZgm{pBdI{u;Ly?RG-6 z=yc_Avmgevr#h5~7KAqezF4oRIq>KLF}a#DBsepfu2y2%(ms=})<@}T5Wz@~$&^@)yU%>^ zB&T;N%tfqopL}A&)7Ol-OUFHk;_fq_M9G=EbliiSkv>@}fBtiqB3Go9^%_AR)9Cs4 zE`^Lp#_5wUfXu&l3K^&O5poW!9+3%b8FG>OB&}@TBUI1RguMegv(J2=B||f%hi^*c z*z`&M&iv;tCEmy$>NB}iIdhjR60%;nwb;I}fs<$IO~A|cRE4gV8p~Ej|BVi=)IXWH zo40}fCmRAYpM`$M(r8#5f_p^ApGk}A$J3(JgEXPK!jW;Gd{M+xn2g>fLyDE+`{ZLO z^Y2|Uq*yAx&wMB*NAi*(MNUnx$v-i5o&VgW+#A_KJeOGS@@C=JeUy^htd3vLQGa8% z2D6$%#e)muKKW3IH+_dAJxTm!A0a)HQX-Y5PZFB!^m`kYQJhVwff&k{h?M8A#AIu# zA@%&AjE;1vZHWM1lt_l^GYLyQ7vdiiOm~uVL!Jh=7Ms~rZ2I)TPE9LIpb^OM>5~uV z$YK+-xDu&WedZf0JwNU-N^DXNf;l9&Hco5?DazWW&q)HYA$_G!KAajW2(=BbEHargeFjrTii8lA&#lE~HnDA%aiBM; zOqD5-_s}P)GP2m@Gd*NC=-Wi@P^rdj2^5X)2uqURpR2&Cux9OGU1D#xEb zRbFus`uvqx<95GWpr5uS@|!OeG9UU(W=PKuj*Jqm5X)4E`R3MQGqZZsTkHl;O^jtK zMAh?GVvWmU6JwbQ`2u~CG~sPgdzDDTPb3_@5X)3pvAR#vRi`s6I(_@WnO_{8M5RVwnoj&3%$$G7+0CtE07zFHFO!VG5cg@yKEmW0?w( z@qLn<;EQb<_@~4s#4;6var-1KWGXhDni<>1x5|Oo5boS3i8r#?#8{?6Aa|enZb=_~ zw**~+5JOZ5Vdd6h=4UE4ZO)9?`070r8@hxfSw~{h*c>u4>~yBuMh{wUx_ttl9a)rtx((I{a%H@)*6Ni z#zcX@e;|@=NU}skvGD}MwjmiDk}zs-lR9AP@Bjw1O)5@OArfjxzP&QhHs{rqf(IRH z8-l!sBx^$!n|M)PA$X4Wb!@$blLTXElp!@35MEhjQF(g7Vj(PjNWzc(#fqJl;bKW4 z5|&~fGNIQ)^tBZ1T?%7bPf^vOOHAVPpSu*sAOef$66@V6DmYVKFulGea2^=79V|3r z^oC5#^1#nkj520Y)P&%fArrHl)4LQkA;N#i#4P9ZE=5fUO5)bWEcDG z7iaXYDxIW`W~4$O71kc+9%CzSEy}6-~Y} zM3ms5!LG5kJ=3i5&vOyMz%fWQO)5kY4M{ZhM39U)HiBe?ZeWNJk~SoP;-c7if??Zm z8!=>}dI!dmjxq956_g6A(hixZ-kjbge~JZnhfGv&PVbU~Lv+@V`2ayq?~;Q<;Mt(> z+j6$c^zJcXm(?qpfz}}misusReY#zABy6{ffjzO_C{M@uW%a>ahw;Qhmxpl0AqnJ{ zx0IYaWBuzP$)S_Na(3j(cTeW1F~(|Yb0hvFC`f-d8vj;g;=^F^O=d9xeMu7 zjX1d>6Dgk4JGqZkfF;$|sPU40NFtZ#ubG08uMvGVBwtIIfA3`ElkySlMvb+3c}2!J z0!(R{+d;O`B4XJDD38ETuBZ>zkTO3&{f!Mz%wTqy$dNWJ29@dKVC;wTJA=#JcD7F6D*@XdE)Z?m4|n zcGLqjW}@A5dY5dS2WZTMyXW*S**Xu0PpQ2xuHK(d;?BOSaC#-ekhrb9$F- zod*ic#Ixu0F4;OPO*mxY*)w`qEaf0u@W7TyX!gAAyu^R5JsfE!EImGVE-1VH_H!|s zY7f+?@yM}|H)rb5xn$)VVB!s#u=R|YOGX~6HV&Dn^^DFX8xJ5@dg(Cp_$?Yyg4pG| z4fqww4r5tIo@`7lY?_7XI+GJAOSjdKIe1lhyLoAfKA19Z1M}0=Kk4L5eXwVk{49|A z8;fJ)38=rZcfpny!d6>#VR<2g<%O_W(f?#ywxyE?2I8x4*^2`MM>mTjq$IBL(r>AG z#6$!;hkjpQ`Oc9P!1_p@3IMyNu~_FqnOHOAaAHtYlYUDrN33msVlkpQOiaF4f?tu3 zo8VW-od^do@GFW!mHZvaKmiDsM4_e@6NR)5j08hD1EQOLE9-KXeqZbG7zI*vq~!D^ zD+Tyw)8jm*uP^5Ur`x*VBx+pkyIAACn#EFjTzx6b1^g@Zu3C%rE*w^vF$)WemLZ9z z_h+U}+Ngyk)16#cG9Ss`8L<DO%$TVP%IVhHpx?^0I?OG~x z-a=>eE**dX_LX{1*@}rHakwT%WJ=Ubr3khXV4LZ;Qqie(Bo48}j4cfG0N6;smAOrw zH*>-(Q(QeE3}^uRNxf%o(~RDQFrWcgCG|dXqtI{aT-CTJLpU&_4}B!-!oAX=A9M!%J^v*N~J zA^4lF0n{rkTPi}8!T{doYGZ4Kp$|MOzq1<1F!WoQHk2{XW6lC3_Cf=2Me03e#l$dx zOV#@`YXEOYZD$5JjNKkJGvQ>e0gxy4p4#D_cgW~n2m>0xuTt-swl$-7Aq;2=7fngM zr#zz^1{ln|k)3iN! z?p(6WfKH{(GmTY@9)O!ovXp?oq|TGc#LA;ztX}2>iJL)-ufA9IaE@N_HNy$P6b(Q% zskzj)oc98VCzL2ADKmkRnr7~?Z6|wA=AMx3n2n%5SR*f2i*KNIEd6?Byu{G=F}p%a zhyX)MozE|1;L7pAeg}9gHJ%v_#p>YWa#E@ic8-}svYxxAZVsA0NOQ4sDF*_GCe1vR z0i>vDZ5|s+X^o0P4al9O zqI1}A!7-poR-*S7+~ENv7QB%BCO|`JjH!*}_dbnlQoT#g4ZxYyd&;&>_05^K8MSQU zZIPj=+?R#q3js$;BTV^1*~puR-i@G@a`Hp(fldNk znSLwN0>?Mmsv>DI|Xi&`r}?Z2LPpIkh`x)N|;h_N)}D#KI21 zuTpcFabLy~h+qkCnIumIC{q$tD&(F+C#{_{m^w4n@CXgS%=BBCu_)v6#>5*E>Z1W% zDfK?T4ak_lV7mcgmKx8rKa49JGc^fP(s#Y9_~Ioe$3=0xd>tET|RyRU^opV({?fPchm-#Jer3Y zOA;|;L(Qn;Kzbe=E)VTbq8M*Iq&yH_8#b+t(jqRYuSH5<(^?cv&4WB-k~mN?c%DHQ z9#}4qF+c;KMjVOAvy?ozhwMs{CFW2Jz2kzZL7~pF$fE?%)J8{f5~!zvs-&j15sFd3 zs_~%1Py|tbMJ80fh(YBs?vk)D4Lmtaf=xw+;;QkWg{i?IZjlL=FPw7i35ArvFb$MI zrKzRty;h>oG1ss$JQ@Th7#bDpsE) zHSV;{sOLy()LPNqNi?ZJI3u?`k6me;z7a~W&(%t%2-KZ6~f7iOyqeH!+v`UEk!%&lli+xwI(!k7kYYl<@_R7 zwBxPMh(O_78*z?BCQ?3Ut)xf?k%mQHC4Q2UF>Z8yJCW4n^v;4H=e#vW%uJzgonlLs zqo&Zgbij+SIi5+Z^Eq~+-t;ph39S_BgAP5_2a|B|yuyeAp}R#UfWEL725HetUKat0 zg~m3=X77o9eCJYnkBHAA6Z&4npzrh~CA(X#bdnoFz$Z5roB7lcIFl}U(6S@2ST1EB z=HB)gbR~h?^Iib?_7ub<81WWyiL7lgG0EG5Zy9JaFnC^l&=x~|kWU1l260(r0q6l=d_szJ%?^MLBd?R(ITp~NCNMT>`A86w3q&%;}$V-x5>X7J;%wCXl>{LAh~b3$Cn13?w%eotV9&EnFx!4|OkZC$k_WhnknxW3)r0GXB8i}% zte%axcobq-(Lymx($Lfan!I{?y20K<>~N7p^?IS41MZ#3PR^mE=Vn`kA{J=`>%{Fb z4BW&l2E;lUfxCKUcSKhY;h04dDL-93H)dg3gc8QRmm~qmt0%`S2x4Vp8`XXl4tdAn z91KuU%RXFv&}yhYXyMTZ)>8FBPdJz(JTg!gndti>hJW{LfQ+@Vv7=6$B&Eo6OkQ=ju)_PiAiZ z1|x#OwMec&yy*ond|Hl5bt|4R*1%JUI_x(rpnrjmg4oa#fCQO3TF# z_H(;^K)%s)+a;mE+mx`%>lw7^z$b1Su!F2*SMGd*k8wzq z?U9L8pk1~Rk)A-+XjD#~SZ7KCI|Dv>WT5R<5sLJAOO}5BSEdCow-;h8itRt;XyD&| z{pIif_z(a5%WwYjuYdXDpMLq*|M~TY|E4qRdh>UG{(t}efBf;+FL6uKl)GO1Z-4%0 zyr?zhK->0GY^p=EvT6541Y1uc$o9^fc$-uM?b_Q{`Y_S$AAA<8K(dA&;R!I7yta{fBf@rQ-6(vLf>e#8he7XVc+|H}5OZaSq2|`=x4#~2NDX1BE%V)3#(54w{=(4YFR(;-W}fkcnp?bO zS>4?Pg5iWimpF4t8wrFN6l>|N6b7iOFtu8sx>Tet>-sDb@&|Oeno}v{dzI?SP;aeF zv({OuN<}Yc0u$%nBSf+rg0zL9bxFfS66LTKR>o0kX03*uQzegp4Tn!rSn2f4QIvhh z5>-BF6CY0v^Oo%l(GeSEgcucn3yqg_e`FzYF2*@9rXmA<< zPYd(ef|^-Nw0{5Bs)dzY0MW|2#hKuL|KI=oKYsc8OYwyM{a=2q{iAmrrnqJ|~%2iHMP;0|)=qyHRbb;;F+}73469ezF}mwngTTtqg5eio0&> zZS>~N3iBbaLy*oeD5Cs{Kzo~W6*9ETt`1Q|!`bAFJmg6o( z*?nZWxiT1d2$B&b*dcTG6>5&OrnfIfm#s?=^t9&bvf{vv?CC4g|0WR?V75y!@dqWh z@9ChdpBfb2Ea*b_EA6a|hbO}9?sru{${=k)qFql#!lS0H6=F7ai@_+7wa2A9$f31D z%yz;5*G_HGY^j9?$WL`&>^CU;TwEo=&*%iX!{*isF`M&lD*YU>k{NVGtfUee>XZcB zOzoVf(!764nt6XC$aavZ=i?Fe9CbeDQ*&!|<*8$o9%6p1o~M7)F%{~!OM`KBj5hG$ zsEB#}jN;!JMVlq3)i17{1`$ib;AxP=PU|#C2|r3v@k6@Ia|^QOh}~st#6!s0C&wU* z{B2~IWGB&Zsb8ykwFP;Et4Z( zA5SN5p~HY)IXUjzO7~U{41bnQif=1jT=8Da*FQ_1V>XFZ+{?$K=dKK0md%&%YN?Wv=Y`T40>Han} ztr$jcIegGsT(wzCub<|eRjav1s=vf;sVd0{b=~BNSs0bS{K|}+j!Jr>RF#|YVUCDw zP{z8kNe1FBlGSKey*MkcjRDXC=kL_e@5bD)yME~f!iM6u;XSJH6Mc?Odi zMKMa(-zNRWM`g=ru>rz~O%l=RO%2B^Y>Z2nYIjO^C%u0M!p28Lk3mAu*d+9jHcy9G z-&D>(*yk}wrHPd8*$F&0dKNEW)e3TU1GvtW95FA0_f%lH!xK8(^9Pa&#lZILC z_-G$ZK%aQt4WFv2^?uNqG8rykS^mhArS8p*4@uUaJj*;!S)It%m-ozRBY6z+s>UX- zihJKsl)wM~5^ms(#ZlLKt{VY~rH^`Z&43zX$-L5L-R8i??1ZsP$*By3!i!(*({SS- z$d$96-xyXtcJD878}HM4HU`XVf4w1Are?HmP8a_uuRWB1;KO6c?+j3+|p;LWy)_HxE9jR^u(vY52W z&QS9brptq=8Z)^+JXx zJ?{k!7|1(z8Ak^18};&!T&gq-9!ITDKaN=27)(EA_p~)wb!R=+4qkYH5$R*!sa7mx z)md3mL<+vYvl!(*cF6&CXI(3}bJ2WyT;!N|5eo*nkKG$Ve96j-!=KYx9AW7)N~+Fk z5=p4DyZ{R?1;?COORU|_Iw>MQL9*EU=+Y$N*(mW3Y9oVml48UjixKQ3DB(vJne8$L z2`OWfkV0eRA)+=$*=ugiK~gx*sPqPF^m(C1JxFJ8;llSNZTFE-!^R-~u^Vcrh5NDE z^uSzOg~I5vZ4g5m3!aV01Qh3g{;RK|j~IflKZ%b@ZlI%QyipOg`k_%_H#$pTtLpWr zJl4-1seWUm{207!WYoaZ6Tf5d{7vQ+j9unL)pjMTJSyFDI2ouvcG)^tNV#aXM3gm} zd0NLJq^vkz4JoT?aiaQs4)z%2)_8Cx~kMxoOZPS6hoz~jO5d*izz~f(-BNbCo#lYhI@>+tTeY~v0&p%h@lMo>xw*;><0|_7NIeC zh055xLWNX~2V~rs&1% zO=YD2*d+|T-9IkYu>zU~$x?y-NqEG|&-4A<$x~AmU!cp7dB1-=HC6Eix>udNU%IC^ zDhz*+_!Jo(Pj6Hh{w@dQ{kDtV=*osSyDOZ3m!bK>h`|5HjZdl~lee$nfRq59NEvYH ziLM?cffa!r+a*tQRU--CZ)1+&)V+y?J9f%cq(`6>7Z1n;fhkD;iIncCJ3ice3etZ9 zrMq}Q2LJ1I3D1pDq;${UV_5qXq~t_OcNFQ)i2W%@$%&NiDAJvQ?^BSH6DeI3X-}EV zj=I|!_CEz_JCPbXZqm-^=P5|riInar(w&I`Q;@b3DcuPs?Mw`qx?GaC_2KMjq@9TY zQ;=&DX#3*eVRj}4Oqsg!EgETYG}6wXe{D;vbk~5Y0TXknwj?LaT-t>+>6MvF)jRnc z!#(Is%TLS@tNf)WN@Pk24VOzI=X?tuG3RdTvKJ~5Qnt>MxY**URwfTjUA~eRqR=|u zR<1jf2c{rrXHr7Oqn3GUo5=&3TUx1R~>ZwvbiGIqrw0uwhcK>B)b}KedZ!k+^>asN6FWu7{Ol44cXh|>p z=t)Vj*@qEof>G4e7fJrFa@A780B>q6^D7HG+3f}C8w)$B(oEkd8z3c+vtDkLp1?y_ zic@+54_!G9>4^)Q+L=$NO=vaNuA7*Y35>S7Fuk3bl2ecnGd(B7Y@Pz1*d@$o?6+E0 z2~nVQPXSNt5(Y0RinRSfymj-`B$GF$ycPF7{o|=gM!Qd4>d5<}^FU4R57gxDsY&LE zOhNWdV3c=HO)^nr3SOlYDcw_(%oNewTJm$MNxg={REJ%~A%sF`HM^5To;Du{k%4WaA&f~6r=@}bvdix?{4p&O=I?k=JsTur;*Eqia>8o=7?F{X$hyA9xN0vlz5tt-_%zrt%&a8wU{~9|I^CSW&dJ%gORZ$lVX$ z8OJzfscW^svy;FuTB~kiTCo+ot}A+JRNq2f52Y*1L^IN=By@^M0{2xJFfKj8dQ3O$ zrEhhcAtkVQ!|6z7h~*W?pV|#Khh^h6idL`HS%5sNvxIhF7v&|D=rc4G_O8b6f(m3W zqOt1;)FUbvTa^;2%=czTTBTn-{6IyLULpOa;`@;X0V)&^aZ>%fGduiU#K( zOREhp&MBE%T!L9IKC|;hTJ{7kJ z$q^?m4t!_$|J3E(RAx@e6uz0On=f+Hl`YS4W}NTTrA7J8&%w6)=(7pzvfeJaEk#R( zKoq@p$GsF%Yg3o;X!?CB36C~YQXvSleXpY5nUbZIX^EXF`bjyhn02|IZau=cy-ZzV zNG*2R3_lS&&%1$=z_4c4YM2q?r{b0!Ij$)O!$lP9dGqmeDRzcnPeC5Wq|ApW z;_XG`7-6iL#XAf81mE9TjK`jWJdUZwq+rSN92bTgYi9Az!W!r&bQbHEAn{{D_{2lF zaA$drNCh+Qa$ekNsFy+flxbKY$hssqSg?ZKCTauQbl@YI#EB)=-n=~Ta{K;wah!L%%l%LviRI9uy>HVF)6P9N!L1o zy`#eOc4;f8v#7iRa~#f_U5NO3R8ZwEYsViHcw0{fMfC1R2IZ(w=s{A+q|}NhgW`a% z4h9;}!8=_7g?op<91Jv`gT#xub?*w#WA7xDgQ32fTg!M|;r61><%G(Y=T^*mFmMi) zT7B+r=fQaAIm-Vi>T(OWSDoPah6jUb=O6=P&ez4fVBS=vJI>a@cvsEsogq-5#@YUB z$79BE*>Y~h>mgvY@*E|C1ctzIq7FtBYka-c3Ds&YP`Y>}P7HygVNML;;4RfTN(2ei z&@s3NBVgtr72}k`zSEX&AFADvgRwoDTWfS)XbHX6 zJ@x(35O`*S!}6NjJ428?EPoc*mS1xS7^yx-sUOd0fpD0#5@=)J_oOKiPX?D6O0v~gY1>L#a^k}?wJWjYin+Ah^RqMJuQJfxVDHA zd}@x8XaXYYSt|yO&p{f?+`3nz8UoKuFl<|MduIqVX5bD%-kR)q)O_^6df}~VysfCc z10)Vceb2%BT~3F!@2+?kS{;nL*4$ccf8nmYzTah5z;tH_7<@iQX*JJhfpPj?Y1c%iOw#g%!1T;>E#`Yt5}SIxn<@5hPp@%{siJ zB^bXxM+q{4A@HmfBfsY^(3wT_gnslDwRiBw!C+p^?VTY|NR>MTIV#c{f@()3W!I{P zA2`jv`riPiE@U6GPG4yh~5eijxxbC}=!=Drih+ zhR$V7%(wC4(8Wf|{sxz9AY9W*5vs3ew!V0En&e>^Y2l6~-K- zAVo^|JT->G&%rx_BBgr~3nm+AZY|k`DyfDQT3xTsk*T6Io?3(tzQtn>UXC*>f8>z} zdjS%LjL%(IcQt_mrF$+XWAf+jJrnPj?nNe;n4mrRWT5AQI3(9x!LIX}}7SzCD$xl>rP)cMU@TM*JY;nz`Rh%zGxykpu2{}Cn zSweG*CB#DHozHYII&}{6b0VdC29HnbpYu82t$wY9DA0D#;PDap+Ll)7mk`+&g$S?E zU7(4S9wb7f$Ccj)noiP~yB9~fLge4!bMVz0s=QiFQJzp`JF)1}Ig)0B>t-HIPnZ;`Y8DZAF!eo0fjJU$7X|))>7M20qxk3Goj-E{>ONQMenfE*%iY`hS;W3}zwt~5 z(-pK7u53N?`St0nFc+gO~I~YUnKkmgEYl@sl8J zC(!fWX;cT}sx`M(&%aRq@D`LuCCVT4E!8r~94L<~B@Fzn(;&Y>*i-{g=^KP!eM->5 z^u0Mq37Vf%g1ket4yMk`-OySkFoDuNMatZcxr@MmzjRNLG81ObNdA_$)*h%k3|FWztaUDrwJ91rQzYThqhbY0JJ z+V2`kYDkwF&p~2RWOVKtNlK@U+PTYcdB1<|8c9m${l+eN=l#;}8c9lL@NIm;zk&nyf=I>O+d0Tanx8{5j=TDmt|o}}5~L$VO24n!rF4qaEx}u8BBguk zw<4kBo@|MkyT7UT>wJycbu!@Eih6%U+DZp|E{`DkyrF2S%abi-aUF+<$jI6>Eq{J-B$a&N<&muAvL33-h48yp9Zk3y+K&Q$L z9e*&{Lx0lB-1ZC>MN;K9jn=?h-h9u3{-l|=HzM8+flMq`DnXji@|-4gcwPe2Gc>nW z!(3T&Z&Q&0A>VHa5>J-aog=(kcX%EMqxv`4=Ira~Kqd>J_{jU%kW0S=i7JcoWL~IGIu^|xnX2&Q!nOp%ovVuOyfus| z5KHhnlLe%0cb}3P=J}9}>(b25OPyp|(*BIx$bO||ruVsyJ&zsJAUAmVRc@q^k z8EDP!ehw2kmLQR10c))<&z`5wXk5*#CC}cfM5}yn7{g_kAOm9o5vkuWZxO(dPtB~= zFo+zxrV0$div>GES!=X1uO^d%%b!dpZ-K#($|cBaSe_T|Is6O~Su$ezTUze<^t=k?>hF9j>51tWWH0+Y0%B_}F z(=JfDr|20CyJWQT_mu8wdd40uK`4Es=RH-wvMU^f(nm`7bUh!yx&)#0k+)yDA8Xb9sR6AHs0P2dVBsFn zp|!Ph0E-MhyVV&K{XM07%ANtGOAxWY1lsN?dj^y)LBxKfbWhncpmYf$_9LZx%ANtG zOGZZ`_&^dBMO6OQ!5E~yU-BZa7 zDAn9rvT>?pCI6U8R?35DStVMegzc*9OiSuk`5h?%e-}u2?eYALA7f|W{nF)ZxhmNu zDTz|#?(g2z>V=?i)1?}VY+L+>FbQ`FLi(2`u$<-GTkSA_ROwHu7mds}ad6ov*b zLBRf^aM&jyo5`~+47*r@fc;46o^4^2>kbzH;z~0J* zfvrmre;+8_IdWzE!NAs~3*@StR|Tj)8CB=d3@N>msh;b6p1D&td(>L{H?!%QK@WV< zvA7{zr5fx*2l4b}T{<58>{)9@xN2@K(S9+HvvEq(*HCebj*UEV@86JClaW-d@T}at z#!@dq?>Z5+VHb_01P+)%RLssp5D*?#c}D(|Cu;p9p|pSm)I4%%B_*StLdHuuGNMY_o*$JgYZi6gI%w;pviu}W8?W7XX|{ZK!IJ>19Zbu zT=*giz}=`FDi~as&~ascome25L#oRIA;zHsjs|i2iz0bn7#8j~N2d-0gKWB-1-rLs zQ6#a-=yKjG!Y!-7ia}KVqKM>2Epz<+p~91O83}&NG8np=7~@bO6T3VUUmyU&wwB&Y zA=LiTWigp9U5X2zMCxD@bi|~PZ&j)y&+MvnnO~+<7e%z2M4cB#u|!qC<1Wm(a>5k0 z{zRf2*wIkI__{;_2vl+N$+)P|z6~`4Lf0U6eNp80lZJ`z?CDoeP4L;!T3*W%cx~5K z)fQ|V7<#z|@!V@hpFc7#o|a&Aq-NG?nBA+i78v$XtDG8EPpwa1Zzi2ZCV36sHnC>7 z`lHTr0u2Kn(X5%pI}85OPv|V#++TxNPpr7C+QkTwX?5Zv1LH?Evv_C0A^HB!Vo2&5 zyeVTXkm>ie9d(woMKJK8%bHoZvlNv7Q>G!qL{%F!>nn3ks0nLv>yZ3mOe>p}>9ws* ztvByxf^e2=5F@`fG4eDtewfYUt;#z{_wa$0r$)_OePgW^@?rymq-B?l@@!pN`6BPP!fkK5JT) zUQ@(8Gp$xrBnvTAn+8eNas>C*V+^`iqu(s{jQuU;V$l{EspPz$d@G0V%vpnEm9_@#?!BPXQL&XZ_AH|avT^?uWf0S z4s~2j4VX6EEuf;1Y#c5b(1zW;LIzE*U06red?ltl5#R)~?1_g5h8!4ozXq=`Spzln zR2Sp!*9;GD4bc1jBVm+o|A-Rke)C|ejt{2l=q*r~2cUi1>J499v1zDdnWYqw9uDF% z;bRR_j8*^z`cawDhs2S7^B{2pAKk1azR@9w-Ei|61-k}$Mr&~kM#oe1@OA@}4m7t` z(_EviH-OyS5ylR$K_1bnB#|dt$GNv_9C)*G4f2R0rMnu17qdYgQKa+-8fEg_3Z@-s ziLH_MXE~q>+P`U*>-`mXVc<|z7f4>ISY-n}5(Y1x$UK9!ORVz6+}B^spjd;fp|#1| zVcq0K;h06R23bRq(#2Ht%+lofUW_T#65kLsct6T>xXD+=<>($Nc8PPjC$Bq#0%yV5 zM;4(?YrFhiN+2k!PDgUT&L_sfu=$&21AgUmAcpF2mhMSx*wfX+xbl3E%0e(-#_K*4 z)Zn|5m+ql;?pCheM06X!>Li)&@uU|%W>MUf^##s9)7sr#VLpIOfBQfh2_Iv7)3-M8 z(Q<2-PxJyGvo%pFGPv z?||q?S})u>nHd6W_X>o{kTjVy+;5(`WpwkJb89utHon)AAfR==izef?*B~coZQf+T zE%Us72J>oe;g%`U;WlQBxYo{S$x#tpcvsu}wQhfNXJu{kb2^Jq>uVQ@U3b>yCUAauUAPk-8ab%2cCqty;aSf;X}O2I87rW5_kM~C`%-kd z%w!GxoD<@2|JVORl-%F`!~gwd$FD2)Mb(Pqd2twM?b0slPIzpbJpj z9p8VBP${C>!1hFx{oQV)vg(9@ka+gC!nt?J7FFp5jOOfs7b5CeEj~hb?FN@$4MFbb zYXX!*U~25Y{^OTjg5_z6N>6vaXxHh;UbMJX%0EkqT(%@YKvE5mHgj+b#EM%WRt?{# zSFgNr*Lhh#WhZGNu?2}SYm*qmYREH`6^1|O)^adT??q`oSp|$*>03-=tN{02G84jA z4VlIT{)+*ihE~$xHXGiA9?c9R&p{+?D zqUq$}qDDU7dJA4B5h>jX7Kj6NO5L~N?UrO6seT36RNbSj-nvfLkntE$qt>`3O1%xBn$0Ly)qkT>s}gBO@)FM(^0P; z+D*>QD2>P#0)V;nd_~?oaY~Aq~1<)n;Oiu*t!HiciO3l-t(q) z<<{kKRNddavxD@zcSxBW7(;{KrKr4Lx@TP&bGilTIa{FZVqLBUpTFdsJR87(Xf5%P z=oMtJQ3o{%n(}Q@0y|FZN;5!y>t3$o3YvDyP0*OYpeCW!6g^b1@?Uec(;Uj-+0+pC zCY_PFHVWHm6;{jDW4~(h7KjX;-ZEyaRl4h|`y3cy1M`dtD(fZ-h3Bhhs2BsibuT`F zD&%3*n_X@a!Wif+NO9Se5b-3y<{jlGND=PXo*i-rO>aiIw~TgOw;=IkQ)0)XmU&AY z#z1cwu-FpEYBB^$_m(((6x9~wbZkl>c+_^!b~7wjb8EHzjMRf@u@LxJ<+z@k10Nu{c8^L!z%3t_4N#f}k|gh!+l3$5 zwH^4-!L@s2H$rR#6VsFA?j1od-iq7ixOV)F=Oi$KRZD!(4dYfYV&o6(Q?nz- za6Wg@`@Y|83Fw`IRr^sUch82RLM{cWoSrc1Yi zz6SYDg$$~P@O@`=)0@XnU4AP{sK=6SRX{MF1_a^^S8k3+IQumza~Ta#HpBjz~EQ?(Wd7X_%L5KSO6tj6zodZw{^kl{clinYjlG z$yAtlD>^+>0zt~$6OQF%S1bqJTIE-RRWJuSgXIL2Cq^u9U6l3}4=GU^n??$+b_zSl|m}`9KBKTRsami-nvweb5xXbgHeI9pkUC%X!EVhEOJLh8~AiowhxU8 zL;2Newxksi4RUeLD7&ifq_Kfqz$H1_DK{5qV(!}3y?3LQipTz_cTnHNr?+oi7R}}3 z6!7#>Ywhm&EI0!^;j~}+I1E*Q8 zL*^|y7$&VHwmSEk`K3NqsQXPHGmv@f(t$AZdE`R+_){(ja}>59MP|d`JQz7|b-@Rq zYi_MkaXU`g22WMyr`!t$^>0C9%T}Dk(=%kAUtfVAyWFBvoC{XbsFl8J;|dJZr4IR{ z(hbJ{#jk(<(=R{d-#7^?{xcqRg?jI@Au2=CyxIk_o)1D8yai8%Oz+Z-u2H!Rn2d_M zBQxn||gKj`tuF zV{bAsNGd$O!o-+#&8^k?)4kX;Ps!H7TI(0?h1sa4d%@s+&AU|%$WK9jlASLcA^l*T zJbo;M!mNiq1HxNX=UKfM`1X#jeQ^*ikFmE8!-wH(iLDx9=INNBt=mgqb0G7kpnStLE)GJSyHghf&je zmx6STN_mxwR@xaAidXJkc9lCS+Q6so`lnowiZ#;Z;Cc}bv&Uaz2F>9x1(lv;p_YX9 zpmdLI zCU+5+IQuQ+5iu8J@7`kMj><`MdSJ5?-sUsGK<4tO7ttCO z*XIKbS5>ftom5@qMD|3|6X;pq5ai2?_8^mKZ!(#9u6iqhjj-vOTdVb#&sSWFBVwTt z?lW*w_$z+fpWe=Ig(5`ro zVej4`bh#IqB?sH1Owel;SGpH@uc_l+@XZ=~mw^ZQDX4eS!SLT6%<9j%7fj#VgH*5m zIn`_Spm5Cf(%f3obI$6L?4^~y&uS)n?fECI%-vDZ20nB8K8MNW3r+SQPi=qBQ}dYj z6BE@mw|K{e)ZwRG2j;=;T`F3ojtWLvPaSz{U?!IBIk#5FUE*9oFSOE*II}0*y`jk$ z=a47-Dc6CoQ`v)ryZt%gZg$q7Gc)cqw`Zer8K+SzeH)dT>2Z6Pcx21JxR@M+yL^;=fx_1Ph5Y-KHT<3UfMTkRAcd-$-9=eso z@dW*Cs|_~3bdHB{=vS(~EOF_SO|o3y$Z@0KipN{+HW|=m3ASIg8wxDOpat-?U*ZYwrO!b zGwXBjQnYG`%Fbdgq9akBimC9fU0xvssvs1~P`kTyGgGMcAgyk1(du}rcshV7GJBU| zRrl)URd#ySou<4B=pI+^_9~96*Sg;|5i@D_E(xe=VZkWrw9ttO%*<)n`#5bq^IVJ@6VAe-nGoTb*=hV(@=S0Pddw6H8ay=@3QIafDE37y21E! zI*Xm}E~giEv>@|}+Q8aXXQj9SxL`&*;I1l}b+>mpQ1uvPhv~@}xx2G$tQ?NkT(K6O z(x`Ujv*n7(5pRh7*V@$C+DQ8FGoDd}R_zj*>aM+3Djmh@Y@f~*-Jwf#I$c)1WC$Gx z&B}gRMM&t<_TZ`Vpyc*BbITo+4+U7~ionx_FxP`}0TMfd;$3++Guhw>UZJ!rsqM*Z z^Uk4|nWb?A8C*w;!Nn8VziY1g#`B$+v7jZkEXK7TR&>p%E%RAkK#2*<%j$DKC}*zN z2VDZBFW(l)(NUIQnswk)iT_aWdS+JD5#)UxE#6l(qMn1t*Encytr3MDI!aELR{Czd zn2(@8X=Uz>lQr<^sC;POd#;E-UCOv??m^kyaWkB0h$L%%B!kJdd-v>)D@?i5x>gq} z;$NJ+akdc5h(CgqwWCE@tAx&Tlo>OqxwYiNPL-!7YMmXKBP{z7ygceqipwJv?s>IL z{y2hcwMgj>17>Ch%+aMTvGI(Q?zw^ti9fomtoKXz94h7#96?4}pzR+0d1mg)k+*|d z68(1D6M0v3AOA$!^o%3OhYGaaqtDHZ5|MPz7qJDeZv55=T{l?Q9%waf!q^rmXdU}J297mUd^L`(CdV`_#N0(gm ze(A2>pyL9MAh9aa^Pb*dH2l#;_`ctEPj4`d;OH`E-Y(s{-fCvd`H>koE!XA!(ml70 z!TLv#Iu#gq58FI558>!CU*2!K7fE7V`H?X;-_!G+uG?uV|LCHD-fz3;x}G*ppu+Aq zp59>2!qL5=FoH>XWEM zp~rgeF*2f=-gF1yShG@uWvmJty6=<;FemR(rm-k>=_)kO}A z{oU_=^UJS)N}V|#U8>Lfr8|~Gt}Efv(}azT>hrdX<>=|J)zR;A*f`fP`ETD-Lr1?a ze7nyPBpe+r!Vzzut&ZQnFzi-yYqkB{g+DUU&seEi>leH57c2GUF8sph*&p4@v)&g` z$AB%2Yu1*vI^l&@gK<)3o){Q-?38K}T_4(A{d`$ec_Kn*GQIf8*&+#@1_zt?tIeJqp^A%*8xQ>V8;Q zsP!k$GS7-YN78!Xo;j~KyA+m6;pz2YFLo8V-#o3)w1A^aOfqEtQ81E(edwz&2IL>z z=~cI^<;8K!JXKzSQM$w=zh%A`$Jd@{XT$}J$x-r;Ouj{7 z>xg~3QeBvmrIl&*jVaZmBs6JTZ^~|AO4iZkk<=2EE!~s3;;nd?wQzKKNvA+vgd`aS zU&HWi9!HR!b0{_DNyB8l<9Nn2o4kbslMuAL)}Xp=*PEbj3Xt#2ID)*LqsiN$hIwle zhHGnPt%ez4;3#=JTID3IwZHOlD$2r8z9Y!nIhwp3>MSStwlIuZGmCc?(B>W^LRT86D_nF z&B4_}1&)%pW134$Gk7~Daq>ia^R6m69B8hCf(vxgF zQzGl-n>r?9()1%nOp;t5tI5$*lSD9((t90JPv_^Qd#a2G22y%dkv=coQ)P50p_Cp~ zq>oGY$TP8>IB8B7I)E7mX)+gOnasq|ZzDRz*Z_uo)Cr0tShe z+QZ2=NVGhGx3BkE$=ufqqf#QPg_{x}mXUlF)SRuWop`P6UG20G=Rr#ESq;}$@^5xp zh|Mwmh;fLdF3*SBTV4{QK}rv*w?OHhwIL>glpa)XfzmzIP6z!;=|S}tDBV--bi%!q z9#n6E(mmBqpjnfm_!QSuS7g>2H^GK5t?bnmONngxZxfn`Jn~gg!zt0>$>PT&a4iJF zm(qLM-JQ_NvADI2=mnB@P*oMj26q-evuC#mJ};#w_0SsF%3leT?%6GZ&rd%x%q&p4 z-s|&dR6V;z;B+ayx1dI>OuFd`;8?BwkS0#kZpO+8#V^?fwOUb^o&b1j3<8Z?%UVO= zd+^2NB>{@M8fRcQe6-h4FDt(Jru0yH2@T0zipMG>Qp|= z(I6WfBYIgSo4XAk(W@(wL98;(T4%i~ALgz`t#d!!XG=AvJ)KnfVM-@>GFv<)L(p{T z&z=i<3RJ0M{OeIxLVr#_VjLFv{+f<=?}q2feH(HmoVI1w8ZozFxypALCa!?w-CGk> zBUTvOPQyGEKqze~yr+Q_r6?cfNQ#M~!h%HF?=1Km-!EC@kjkx6 z!H85rTj)rZ6AoJmr7eZ`R*-IIDeC{HOha16$l&%o2ZiFxhj~#2wUN!4te*4|os`Iq zup~}O0WBI<;w{KmJ#AIZeq}>EF>Vqx?77)aWN#%fyVS4SEg7XKAC}#sgf(Xv9n3@0 zhoA9D2rDl&3M$s(G}n&!J2Ap>*fnU_XgFibVol@ao!>FH?m z-dy*9j4L6vrGI(`j|vQAJ(OD!hm* zcrFpa>!tMG`A+J=IW zWRGei8Jk>@thz^r2BHPZSe%o76~iF=9aka>3Li zN)DG!0jTXHYp{6if)Q8I9J*$)h}%jy;1UG+A!OR8_^w2|o_=(BJGIc|+4M;NI~&9+ z(I%uXdWKi`>8d9BRGXDp6VkHYz*Q|%F4Cixc`j;2J?LJ5^M2``qgPQ6Vl*S^tLL#? z&!ed@|6L;5sY*z46;&%U#1OucfLi9MQh~c;#2?8uPrxSw?IAK(Le5KWL9HDq-HV!6 z^nn<^Ce(H>szm_qNj5|}y0I4W=RNQFL=3B!U4?He-Sdg)7)5D&RJ}ZJyJxK#-95x; zHKB3$)HXvlhs^0{8K?Kh-BYcM{~n^Gp1_RrR4e1ZhfLA7IRIxb6@nqC`sfd}&6h4?!YI zq;$`|FiL$05>XO+u-5-DBm%N2X|W6!f^1sKUb1j#Cq8hTcMk?cd4o55-) zP`Y=P{K{bOA;?RKlT|5QIsQw{Hl!=t?IoJ%RAG%DDYKjHg?x|KfU0$YGFNoxe z5V$zncS$@H9)H`%W9GsTq^=B2<^t^^E{-POeh`Rs2vS!9rF+NSZ*(U7G<3-$^*~>n zDxKXm??n3TM|l{ulpc#!M%wOZ@{LZ7m(qJ;_I}$PO}^2o@ltwh=RDGO$G6-V1U$s< zW09HkeB2!yu`#HAh~2dkD&0}78yzhzJ)c%xEerMjxI3zKW46K&yK5!Xc1N{tOvD&s zcddj<_jKLBx~@xEdAsK~2OqvM-(iSdnG$LH=6J0eGdYIt#Uk&w-P3hUh#0b2`WBhr zJYC0BkD*KTc)#tQu4AIq5ahW8blv9ZI--D0L%v_&dwSl}b#$_{$#AQ5xKe}Ce6#y1 zKeI5MdMC-10xwc+c76i4+-^6LZxBqg+l@@s=8xf)EBP#C2)A6BOY#Kl8x_{{D`gy| z1akIoYuM-#AE|y!!xL1*hQD?iH@eD4YLpt(>ex!8^94DN$WxnVM40L_bg3@ym+l!6 z=8O!PGV?uc_lyX$VTMet`Igdm&xkNGXb2L4hUeqHdq#vI=tK8bjJL;q_lyYBUxqI3 z{{7O$i1dOFyQk`zP&9N2MeoYQTWPjlg*tJh0 z>zUvvuast(67UCrwba>|?6@-aQX+47r3Cx|aB#E}Z$Y_@d6+|xCpA3hNgbX7WSWZR z*6KzNn5lKXw~V2!Lzlf%iEzOe=|o}<&qL=^IfpKu*B1~4^xk|WCMFGC4ouy&?Cm{? zq#mA4U8f`m`A01_J)Zknp>;wC;6i6^hs;&pL(O0X6ZrRulO$;6NQE@4d?wK@XQ{QfV5?; zPIxhEp?sB%BkEYkMiNQ_xru$nnCmWnu5vGtGlIU@17pXhgxL&*yr)-+xlRde?bt2k zvZ{lD(WR=?R-Nlqe^?{cis=bfjQ)WzE3cD(bnh<(6{EN#68L-Rt(P>t&yX)Tr0}B~ zQUL#zPH@o9s)u&vV2K|3&=RThem^-NBI9#3WMF4p$iVqa^p%6}`rB4HCPL-OI5?8x z)`n_Zp-UNhaWc-J)S4G6O8L&e`OADVPTE^>95epLbIdAi&trbkQ1Xigz0s%chm9Er z`jZEJEYm(uHXTXpg?r|7+V#+-GgO*S=_!x;*7L*|;XiZXzN=F4bhnzdF&+fdw?hKY0QcP4ZVK{m{waLFeUn%a$g^lo%U8*40qSen#$p? zW!;ckR~S;Qa%xzu$v%Ge&c@_`F-Qs-_3G>=^U_-wGCp22i+5Ju5BfQsMT__`$RZgP zSN^24ymc%C>NT@)XX)9XKc%ynelP}UC!<2{pLCYD-eoMhW)|-(_(tD94H-hH+Mroq z^(n^UhAq({<_X!X6s-a#gZ1XkDl;)@3=&jEUsb7=tvCQ9;H}B;GrVXJbJ67^I0rO81;W z2BeQcqQPKxCZ?HSvJ@1Jj;aXx#u+CU**)@~4%#YO~8j=pm(OKk89zvUrK~70o zmyQQHcwP~sjK?5jV^l=@qha#g3N$M!i1uIh*HMiDqT#@vl z487PIGP!+u52GHLjY;rhmo348*ikPrd8Akz?8D9k0?n<}O50uKChAsB-Ljpj5o3@8 zGb#b(Nz1$=YEJw=+Fp3_=(qr908Bo#_E%hWochwU()CC+IX4C$*9k znRi{`&h&sWNXUt_-HC7QOb-}?gq%p}j<2*cJzxwHaw4URlhX6%yt@H+rVxxl(oUp? zo{?h;!5Ad%L`wIx9a9L#AZaI1x_8jb&J=<%NZN^%E*hyP8&iKMH$PtQ^?yS;whV_p@ zj!>j@Pqi|ve++VjBBeiw8+xbD>cE%x%UC>nJB^KDJj-r@7ZO>T$u?s?bzjROAGuD3$ zGH}K~+eJzCZ1L=>GFGHrl$dXifT`2|%~F8~FGY`cCWnkcTF$6Q@+XV6+0&d%0MOi8 zv%_76Dv15I3}tG=7$n_{iim&IGEXZrbYG5e4iU{FrF#x9qteG9p(aqech1btc>6I( zsEL&BEx{SKJ_ZRjk(|^`Gu~Hk zKpgA5O6pB-v`PuM$zZ8y|K@Le705iGv3rkBWsv|l|3AO}(6NW!i7`8~0md#1$yI^= z)i*l>zQ-;-q-q&LJ`Y;vDR&0hk3nk87%1ISz|1tz+~R@;B)ZoAzUX2$#TewsjEZl6 zVr0BSXm-9xLvwqhjd{l0>}SPNczkB$P@WlSAjpI|HKw@5=Vhki9&TH~%M)CxXnvMF z0aMM?PMY7yN99AFoOd6QXR}qON_UTV1fEq7X3t|HweD_6eP*+xI)J--#=UKJFpO0@ zz8=V}I$FGY*-Npbq4&&KUntNw4W+xT*!Yfup?mv|sdnN9Sc7hD;0ry*Zr(4r0i!Zw zUQ9Tk%#|D9TX+7(v+j(e))Jpg%2Drd(azQu-t`R=5A-LGGB0>rll4N~$va=PFb41C z84Doz-4JrWd436_+%>mW(+r?GmPl@`^S#@ccQAJO8kHdgPQf*V+%nJS;R!hA+~O_E zd-%68W8Q&wMk{alQzHum!k608dnrGD`@7%$=9gdpl(H6$n{;ri6l^0G7e$HGVdqsx zObU6qpZpP}y7RRqW0z=&9puahHMWWM)2&CCcQ6JoWEq>6l8{6>+<={r?bpm&!-1(% zuy-b{vNKh9dC;{))l|{@O`a%NZ|zpW^Sc}#zhSO<+AH2ckj)`?#f!|VP;|7L7Y3}b zon1DE-PJh~q~K(8)br-!Nc5f22~&_EGBz0^B;K9{tzi3Is)E;9TID3(KcTbe`s^u4 zDw#3^=8}XvdVWewp+%`6v3tv&0PB*UaLb1^x2< zl2yU>yK695uyP4znoAZ+Sb~|veNEPzH{-@!A-UfzI7WHV^kj^@05}7%gk9b#+$xW__t+vk1Kj1Pz)tBWd|d9nkWbD3)>^yp@fCubu*>RH+~MOpqx|K} zqE0p59)6GcvGc+2!ZZ$+{@CgC7!Esw*X1~kPU)|PAS;M#tK))?uUX5;P_>7E&K%I; z4J!}a`l544!ucvuIg#y6dJ@w5A7ZiWOu!MqZ>N_l32U-g$X6abXPHl37v5Q?^i%C; z4isjYg7a@`pZNz8`Riov+G1_sL$&`YQ2)*+@v9+f3SE-oWR=ku!Dkyqzu$$oU6x#SW|?~F_>blKs5q}!cE$HANh0o8X(w@oW*qSpBq zfH;`4AX@;Pyz7=dw_45$;b36AY&U#c>5lJvFosV8ZQoY9<3Sz_otJ>!x0UX=N(V#d zWg>oC>5i{-FmzrP5Z_gLA}w5|^n}-wq92{u*un66Q9$2T!v{Mb9s%HB2)=CRb!rGx zRH=om@I=GnHW-}-$IxcR0#~j;^1AY>+8)SJX!Kf_|QwWaRf0WP?OX z_f#39x~Cu;BvQJk${5u>1=%2x(mhqisO~Aq28opJsWL`bPC+(Eq;yY}@u7HAkm(U9 zJ+U2ns?59m_F%a76l8-$YUsq`4~A<`K{iOFbjM#m7_L19*&vb9J&nXr>?z3fh?FiG zsVf_v-e9=4me}&!VMN3hh`GUfM(>PD1_FMx-hGpv=xSCH*@KrSpke4#NoFNWWKQHv z)06C0riAN{A51aQ%CxHeH~%>=H^iouwa$gqtFVKqTT_tPF*TVT!}OWuhyy0XXX4rm3mZygK^kXkmwQVA5U*E4toj`JtC!hdV?|6 zQ;_HpDc#i@yvZ57Y9&y*hrd4=#9nG8w^aIg4eM`YUt?=hFniUW=N!T z(HlJ{$h(d8U|6x1*zzV$Cn%F=;RJy-rZzjdGq|NmEm?k&{g3nto(^tlQjM0sfe(e7 zBy>9ESMZ^5lZ1|CdZifsn=`}wuc^!SbsZ&Dp7*?YqoI4I#@|@THv`jhFjO2j^n-Tg ztqf-RPeE$Uq}OUZ3A}o2frC-)np;aS+`y}HC2lQay#5p<&P+ zBG17iC4JnR#)1*#yi9t}$)l!uwrFN+(B=F1gO-;q_m|uo@;)Vf(8h(Sc00i zw=^n<^4yFPWtw+bl2*+@)s)bMW74xwSYSSxxTaVB9#wVxbFM?HPk`pt^XgSk+O!jS ze2K9645o%@9Ao!Z06?G!#H-z0PoAAw7i0Gxn2Q-P7I(l%eA+?^TDzNg?0k^8{ZPhDD%-?FR#@4d!Wx64_8PM$J}4?Z+V3tBg)|JbwW z5&(gaD42hcZ&BDfV$ziFRjLQyl`-YYv?hxw)k$v(!(8zrq0E1px(d6Ns5}F65gm#0 zrb>ld?-G3=PzA$B0>r+nRiR?LM!s%XHpWjH=FJp78h+~9Y`0;GFuBbXCMQfm%E#2A ze6UsULIDhM*36ossAu#~#eFRj$w%P4o;M$7MjRF1z6;5&q@aKob;R3?Trj$5>Z6O? z&dS!*Q8J(JtO{=*r5xx7FL1F&FoMEu7s@H?^*qQUz zi+lk6+-0=9UAV_zI2b%X=Ou8U>8<-^c&dBEfrF9PbC*hVLicB-KBB%VSIY^!<>(ZH&9)ICrZ2KH!&qPWWXRD`fhr5pmZw`FeK7*mPp9jPOwPh5IZP^}5_N6DLxU6S$7VlEpZD%GF>*xV(#ygvkY zgDa)e?G$sDAyJjyx>%+fg1gz0(usLIcj-m1hCp}m+#$&RZ*K_58JoKtl&TX7jdfN5 z!04(I?q)(dfx=^RmyA%AuGE(&>vHG3c`2Pj|8tl9^I`}rz<;*CoCOv*XwL$6OoM!o zfU0z`>B1*wH5lY<%(|)ZXb2>P&{Nb7HeG7STB3_he>F_m3%hDi43k39J2Qo$d~=Xq z5*a4XS}{m*4iY?OsAKOK9G<76XRR2IuDQKoFN_4>%@kaU(VQs^%AbQglgJQwMw4Oj zbC72eDc!SH42z$G9Fj=sp0#3F{G5>%Edi($bpe$<2j4dnqnL?nj{4s?NA=6e9jwRt z0FrCFQ6DuYy+$PjqeiqZFTkgPH*W#iE-@T?VM+cmd$hM?gw8myr?3z!5jckz;y z(R{wPn!L3YL+s}u^<-{=+}UGv2oQ2Q5w9zAZto0%!gJhNU;)bZ5U@55GGGF;z`4Id zI)T^tK@Q5Skl!b>z+reu>8t^|{F@iHz;3B zM?PzA@63YN9;05&*O>);I`o`z_^oQZ?X){2A(2D&7=x^gS;-EMW`So1`G|VWt=0Ay zv%s!*aA!gGQhGzc+BkUkNn{pyc921^a~EJ+2|$6fJv+dU;5oD$IWm>K!S2l~uZG~Y zH>jr|bcTRY#&Z`NU3J3qrE6jb-CSb6PhjqnJF3zP&Ov7g9Nv)(0k0WzZtu*3ygt2_ z1VtDVRL|zpm01yUmmN}dLSP6ybIkmjxl3HAN-y{ey&>>cZA^2Ty99t2v%nYtXAR0B zcoIEehQ%D@jsz6Z>Y3w}{jngwV}8!>SUq#hXYOlmZ_EO{Fv6b&Pof7*Gnw;6C9P^y zau}Ee-m;W0HJH2Ce^jOCYgisdl2^|hGizb)Uh48{7Q9C3=$)h;Tfpa4&Rt?g)d_(i z@XRsOLgp@eqAI;0KAvj8H^-~DEM@M-+-1bP8iLpRDG2g4Z2{9f<{*D1polil9P_0P za~H5(4MBn1?hL`^t&W+sG3VS`8sNncDCxviL>l4j%>vfO-TO_dPIx{GHqRV0)n@Lp zN2=15WbXszg;3is;Bs zPz~K`P2Zq&oP=iE#PSLUpxLfvdVEfzizLf7!Z=OTV7n^8_t&xYisfOMZzV@%^d2OmA4CJ*fL1x+#V5WJFGgH$vw^n0) zG0z6Dn!s{L5banjL3-En+#lUNr=0m+OPAxs{^)|cNBVH&-SdW-+N8O)`t|fj%Vx_# zYU=o%)4T`|Vc);GDr1`25~P`xbvdix&!pXR%9&=SxwSgs#Y{3c)`mo8k{%dymp3xy zOOVjDsBisb1+qI{%D`kT&8^i~cP8aJ-*p62)t2C0OG_q>Jqq&djwu|N1GNN+V3E?r zT=i7;?iiJU$zob!tM7e5Q^s17FIS%pOo&r;|E!d}ILeYG=YN=crKfC&VK9Fzx%;;2 zFe{gAhApdXCZ@WWB__NeBMSx`Kn3Q#W)9o_(={ zC6bngh-t=Ge4TBB9Csk+v)@zS$&WSF#vZsqWfhZYwPhTYXor0K)+nmYnS%U{rzDtqq9wMv8&hy87;F{UFyO5mZxu z@+|Y>@J;K5d*-x^T7s;pCDYMfDOc_{#~UB`J_XIK)igVLXDL{1(ruWpw6-0X60-yu zSxb|V#VzxcGBZ6iw|L94@xP53Q)#p_T6tg6Mgjrtsx7^h!i1)!%RDt*x|ElnnS6`p z))A9JzE!EpWFZTnm1*^jDb=N53rl5lKizwT_WqY3$!ckmtVp7qwaUQE5zVaCFiaH? z_fot=t95pxVQvv_C0Gx!Oe#ok7j9|r|m5aZ;!2wk~L zB0KCi@nr(g5@g;ifJpVlSDdw;L+AM=%u3MmnuDfiJuL+ zPv55oo2(!wX#rfJKQ)}_@4!S0&8*o%$bDYBn`YPTdPlQ=tK2g=W9ia#Djx0a;*}+EJNILf&qkq3({qgi_Oci4>zm{=$7l)O zsk1;iJs3eJW<4;;Lvwo~`g*4aME^fT?ux$W1Tk+yON@8! ze~8j&-pkS@DEgugrLTQ`7kyUx!ApANw9$WHyNA7Vo(K5RJ}ko~6qsbj2F*BJ0PSSTk#D3DTvO*0nb))O`-z4qgb3 zi6WZYlhG-tYI3pLe~3osu=)~YdM!<+7k8YG6X0(=Pmy^rT4KC&|3fr7b7z(=m(Uk| zXmsuCyXdn<&r5)2|NQYE{`nU#{)1gHpamCT1Jx8IY(<{DDWQ^ks|%lVu>>zNT3S~L z@ig>K@f(;Yqq((u!nTGv45moLTg#Y;v~;(hDyLtGa8J~KI-0NN`HY@h$vmBWyeK@|`a*Y#WC*l}ZsqXNm-^dQIVNDVxojIdx4ijm z(WOfrd$qZ&6t)*C1o|cWDCrm;M}_b=zM4_ggl$r%qurc*_!}>5&m4uNOBp=pYe5#2 z>nS0?JUN&JvUC}NSLWFVFp1FKybV?bhV3FHDmAYhw?||2q;I_iE~Al`E*B7+SOp1C zy4F{P%RMuJqWZ0er_F-J5cQ>dkJSso$|_w{jf=zR6W08zJF3dw}TwCrO81f zJ>e@!`oz~H^oftPqEGzYJNm>2P0}a+MiqVHZB!lXTz5%zr{d8YG0mds^*1*mtdQs3 z3zX{Fm38G4A(XYd<1A3)Uu_w7Lc(X1Y0Ea% zJ$<<+_canX|A9ac4}!yIv^FofqAp6oh;H*AXz3S_ST5^< zRF6*ld}M6Bw(gCtcFp0)fb}(l$y=G%5^EKBVhF6)7KOb?Xa^guk)NzL7MJ?Q7@K|iO{c%8Cnnd5geed6~red5nS`o!;J`ovjp zj(j)H+9eXcP*N^xa%4iunyF}!nbUGksAaxj&?mlJ&?mlF&?mlB&?gUs;)SC`*?7p0 zk?#^(yDY~Sqvbj{;}61Stih|?)=W%%Wtq8Y55)NeLV)ve1)5-MTC0}Kz33v>c^UZ{ zBR%V|m3d_fl!y4j+vcV{kmwiw9q02vrUwz~+D#idWV&{FpME#`6vL5YrfZO5xHc(< z-24ZV@r8d!`MlV*;crB$@7+i&0i9salcRJW4qA$954-0Jn#Eq89sy)=E)9gI0J|$f10NH&bPp^w5#qf(ja%Q^z~}I--FpHn^R8?!e+F-Q zVY6+$c@vMhQ)`zdXA#}Cq{(TOZ_$F0cbwNQ1Ga8ho;pt&=Gj2zPOaT*{oXEItW-Uu zBa_0`;H`&ii}K4u>iMEfu3Cef*g)Z8S8pw6*4UcKnXSqGcDH*08Ab}NLC$QT<>Cq4 zTh2~b7qakn%RLu^Ibzz9R=4}p*mfCpvLq9w{OFW03#S8`U%`6$=!cOBpKJHRysA42 z{Ln3M%~Qa2w)qo(LbD%jjn5%&}U#jNRv@+qrM;(pd#{QJc?8H&fg$otHUX>gDs&vtAM* zZH+tAlh#b(42z#T?iNXJmtIL-s&T9I7ZW@eCF&M1KNX;)Zk2?W5{A;y7CPF1ce=VT zzq2Of(W&}P#rZ)1=1{9Q_^7=lKu^8RY)r69@*#U8!vWVI1$u2!pexPh`83P}STmHl z)!53E1xojv8s>42qy1`J%AahG0ZTCLrC{pzl6 z#O|ws_PnTt=T4A(yyD&kZ_lkNU7VJi1Iet3waZd`yX_v%ePp_cw&jh1&dcXC&~OhG z?|*MBfhN`zd_Yi{wzo=jnao{h{cS-Xc@oKuE$qiT)RlW@JY&G(+9 zv$EEl$%D2~Xu_8BskH28+(V(v_q7@z{I~IGe^SHhS9OE!-_G%oI74Ri>RVzA*ffGypcVD9-GbLf7 z^);dv<8C*fjR#Jj{((cV2OJGO;v8u`LrheiVZ|kZv!-=uYMuAv2c1;3bz=o4E?aSk zl#OL28j^E4$@B-!A^G!v|M!3S<=21v&0qe_AAkMFufO=^*Z<}J`un^%upYEg@&eI6 zepG0PlOO(vYgqMIjm>Bc*Z=DFY<3R$rrytg`^_)E{wY;=T2D6oA2u6{T?3z*qloCV|)gswFnlyPNgLW)i>Y6_#I{9kRX|_i?i;K=+UH@zQHVc$)cK6L@6JS$d^4DhV->m(c9TdGOknn4>cJ6u(^4D%BSMPRk^=`-J z?-mo^?a0L4=KHSE&aYiVWb(iDyQz*{9mucUWNbH?+D)bGrb%{Fue+Yb^0nhQi%aH` zKqc|}!(n9|I^({M99R0gufxhXtc=5a^uu)MVb0E>d4C;tg1}*8bC|3iHWpAXhmFON zd6QC($)+3+nRV4+GI`kPhKG&GVX}D`ko&N)IqZ_0Ljn3&KTMy(3er1;( z$nm8p0_y#Tg`(sY%Chm0lSEOLjf^}&S+=5*C#v}mtIqYm3eurj$qT{#^RJ#Uj-o}kbxfkJJ<%Qtue zu^AvXMFRQQbeB^ut#rYbYJI$fRaL-3_~uOD=THUXm9TLiA$4cshbb|UQ0wp?XsKNL zkcud0MrxMMj1e+5LI;d?&&l8=P)9hJBP3{q;Eb4%R|4`fLSDQC8V%_fmEHU$Cn4G( zj8F$7rcseV$EbZP+nO@AwqiI(sDlyXI$~T$Q{sbouQo8y3lsE$Tu`j9Ca8nS%&a-3;&7V;k7j?w7e~t=ouiIfS^YGcT75Y@+49Exm8)p*#Dq{TjKLFpjNX?M z%IwvngtcCFc=0PF%%vQ}&$L%p0^eY$;NHtB!&>hoY;hqyggQeOCzZvbKeGL>{=g{W zQ0W0T{J06L8gBR*W)w0*;Aa@U89hCl+ao7sS?A%>o?$lcL=rX#cJ29>JV99yW?a7` zde(;A?uM0*u^=lF$j}x^@{M&2uGSGYWW5hdqOK_C|ca`B4@Xue=tRHuap=+lf)T@8n;M^*qFkewH2k@C6lRgr$<#u zPwUZ3DS;_rM>3=*Hh=UmkMs@3d4ZK$Fucm-%imb*m93ke*t)4qSoMuRn!d5NDpxfB z3Z+BiEszDka>Op16Hp|OGsI*;2QP48jp*<-0H`AglU5*h&>eYVVq);q^mA+J zm4FJhyQ$?H=u*IYgf zh8t&lis=cO1672WusB^9+$#aGx%t3ZFjZ_37#lQ7EMkJ7qa;u@C^Zcsq;Fs>?C6j5 z1XY7;x1I?&^(&0`3Vl~3OdYJ45Jdu_1jD$(Fs_&fE7ZYitF&RYWtt>VF24GzZ!_hPd(y13kEw#weufKZAgY&SY|MZzW*VlDEqiOz;q!Igl+fdI^~A@sRfC`z7K>o;5Y%M(-{;)VFkutBO2sgWmW z4#W#Vn_+`^A$%iG&@PDA2JzakJV0zm)+VNkcgPvSJo3sq0RbO*Vx54HkC55TYVDA` z9hwtiKlui~f}9~DBq3R=>TdBGd4fU_JJ=CB*kR0zg!LgpNy831kD!t~F~0-hC3#|F zfk2ZyK@H(^A=WhPSb6S{F@!H=5od$4L&kPQ7cMFQ=D!@5JFb||AA)_I2x+M$DX zsGbde>Xm>mx!oPsRHn|S9Wu4UV()tS$k%{4s3g!0&|L_P4n+d;Vi72Lg)xL$+aYc{ z#0??S;efYvK<*Gll~*<_2kbNAJ;MRrWf7k*d16&Ppu`S{5<-8&0Z~E_P@b5)9591L z!dh`aIu4jY#0q8Ejh|x)dO%(dtcDOs91f_f0~!#qMR|qFUkT(4BZvUxa9|B}z}H7i zQeK%%9f)-yJUJjfDG7W7uMiEVEGL%36(AZG~MaVj|s?xUHJWKCzr0cl0-R0=_j%=MHQ zing^(sKY8xw5uK_RL14wGofV(hZIFTO6V+j@#AcPo&YS`S6C-}JuvOKXuCA2RcA{(U=fJeewDj{z?!N-t02^HHb z^BpAyh>uU-@f?ja(HNFgf)0y>HIcV9NVbRViMfp909lmFLhuR+h@e~yVXq*0vVgWH z5HE=$*b_*V!~^ie`V3)Y*>2VhCDv=I_)0WdmcF%?K`aJ{1wz7OkwEJq4cL?(#nG^; zVeG{q+7q+1BjUc2K!0GQMWN`&GH;QvCd%x>lSaZaL`YbonRA+4Dz+kcAPlFq%6kpP(}_pAp@cGSQhhQ}x^`%(GZW zY%~ik+y_(*dI<4jDHUxs_fMXntIYkACuj#Mg7~ojtC6#<8l?8f(1Mck1Oo*%0)T?N zLf=DajAmJ-@u&ur#t6Ydgjs+SC=0q`geW2AEZ?AXGpOLolu5w_?UC-W2~fqbA} z5CfOZ25a&J;hG>^6Rh6^DVrc=MFRDKGMa4BF;1o_B!MEJrzV(6FM&=lk5e{3Y~bW> zd21=Oo7@|ZCn&4<$6N#J8BP`jc|W*j>FN}!)7?cP!y zq-=B&V_Rml>l3AX^RY%dqgI|kHW%nXoSG}IY-Ru>C_A_|&UWXM{2bD1*CM4SHqHxd zI!?0|1CAbo{Mt1k@+(_*NW!|@?)pftY*cXu_Got@$SX)R_G07-dJ&$8oiLw1M#UiG zc7}R-g_c5)^_b}dd4wPr3FHH@wc{1#V|bU?!3hpsYPt;_>^w-)W09~P!cL34vT37d zK_q-8gvq$k>B;$xwG~?&BbaQGu%1>@V9E#bVjL@Z0^3_8Oel|b4U@e#@Hc|Cn)qvpa@7Jwmjrx3^){o(!UAUwde}9h7FAo+ZU2R9ig(YeKD@kR4Zy!Bur&tLqk4B2SYDyP)FFu5C_=G z!uEwcu?{xYnBaNg>JZzJ*c3Hzt`rJ)&>*_$ z3G#us0S7BiJAMvhYEW1a3TTQV0by57Q4VJ63?0l3$_GHu5t|pXAVBM(SO5lqj$w;o#LhyQuyF=5R9;!fVAo*8W{^$ugP!=u?@5q1p0j#b`{@DU>U zBVfE`0urq=yd2)t2RgifBaaB`O9E}hVh*8rd1Vr_W7h3(YKsIq7)~vs>$32(5i1fl zTMoFe2(t?g$?V|)7Z!ncd1ZZnz?VfRUS3(hA_6aKOXPzw1R7UfAs@^!1n1?Ib>0D| z)=Qu)7y`uYW%+7-2!yXZL0M4y0R74@TlS#F>EHA;>RlZ!;eV>B|!v=8T3%Vsg1@$JAY1~e#uKX{FxC=tLe7vf zM8)Nmb*8{??dOmwM7QOBXk-YPLYP}#p{iE`bvB(S-=NN>0R`-7;wHFHEA&dBHy~~R zWT!h@@iD4u+D$HvL_Q{W@&x&qnv*A}s%bZQg0`DdlPAd8w421_kh8@J+}D<}Aw-)Y+7yJVBk$1f~PR`4Uh>K9~*y z%dpZh9R%y3Pkx{it_0ftLz`So+5BsrvcPXo2*HEqn9UEeW0}`V6!D* zqEsaCG4vgx?Ghn187~snXoTG*cxr7ki^n%3A7Xf z2!yu;YEi_MK*b=55_ds{C;|c~Q4M>AL68sxo}e=!iLwmGD-#o0P~!;_kVILU+AGK% zV*e6KMhzi%fg4_58mKQ*Cd1Y0T31mNqc@@F4C(w5YvP+O0A49t#wl1%1=q5;6 zkwAt}bBLr%upJpf+$M+{aO(o*Mk}D^5L=g5Xgl;BBI)u94ZIT8_Y-FL1Svx#UFwAl zuY^e%fbjASa=sF11vDV=@A5Ia1#%}x(^>aI70S6kcycB%l#sg#;x^eX)HFfOoe84> ze94$tKG5n`8DHa;_?6|r`Ch5A595p)+$1gdc*Y!DD@ zmv2xXsKObt3CO?5AM%0RA^I+_OaNyHAj0q>tY{8&*?c9?90(WU@$xG)2QoE7ln|Jg z?IZjgqBKL4W>`!_-=`TW3_*8!f}g{5BE&w;Fr5go%M-NSBJ1)5B4H~Jd4f7a*bqLK zX^Ed(EJ~hOk0CTJGuAo^p>cU)!&D@!P;e1sdfS{suw0&4Sql{50!4TxCO8RK0#3rD zEiLC$%1`GLBI0t7n{^&S^#2fzy9%G))K|R zkhB&lk|1dZx4BZ&G{B0!s)c zh3^pl&wmbbFod-_y&S(zDnR;kk|P+bf6||`oWy``mp>Qz(|S0)UFFZ>=O}*`A4{!FCi2HpD+oaPSZamwO@B(QY{>G* zQY#yU{HN5)IyV0)wJQ2b#u%~D^j3!XL>s3+M>z`sIQaDUl>Rm;OMlPuw>cg8=S%v# zc)!Zu7HP`wxAb@MewV+^N6qh#^!N2%Udi9r*vZHUEYxO#lrM@x{x069`W0OvLnl<_ z;(Mtd&||4QS(XX)u=u^yPw%S~a#wmU^}~i|{#)t?>z@7=w|Ll0A?LrPe%RW}e@p$a zGnW6B`fbI?NvuF*nmA~jP`TNRW6q!(HuKY!t$={bqi%OHfFEJH~mA{MprG7YMCDlhXoZvOD z{uhy!zpw8_*GY)zs*fl<`MY>OCS>qcKT&)VK)U)%l%M>4$%`mJ{(F_b%^0Qnh$57~ zi~Oa2=W!9~z0^-wwqgKu{6#4WPV_2IhD!dv$`j=%e_#2Df)vc?)gEb@gs!gs5=ALt zsv%1XT>ifD6D2BtU-c73D#)&D zJVcqw-&g*kPzA$Pj}aKVjh|m~gc>c?SUdrQgfY$=~Prro9A-9-Q)(wiM*=Q@+wvl)tb1#ePV* z;L1OF4d-D3DgRVIi{Iz+QvEENmH$rlGw&<^o$7a)(X<00k%23Ju^;mH)jv{I`TMHB z#6%<%aLP}@@XOy8{^g(kO?=+J`1Q|!`bFk+`Zxae>-hqu(<#7$A9_d{uv-E=jZb4 z`L|y<#jSWO_iB7?=6aQn*Yve^VflDVk98!9$K#M5YlF+jQem(q%EyyDHus}^oGNHi zTt3bfRADF|rwZDbl#f#dP4vshdwP7Y_mLj!z!hK1`SORu(>CSfRBv16 zm5+11Z(}J(;>y>zRxW9D%+i;cq|q^jRz6OxG(W3+oLXs%#qx1#rD?(9@tRs`OUUwZ zYNh$C<>S;!Q=R4G)JpTn%g3pe=J=J5Q!7p1mXA{_%}pvFr&ii}w0xXeX-c|$oLXtV zRq=RBt+WMe`8c)GG<*3twbC5$@^NaVtsBb6sg-69%Ezgd=CzlPQ!8y{Rz6OxG#gSr zPOY?saQQg3($>Vq<2|*~3{UwuwbIrH<>S;!i(HqFQ!C9{m5);^ZBbD^PObd^$-3%* zEsC$Jq9Py)lF~@G@HXAuEnP3&-Jx`Mhjd8`2nZ6=CA`vtbax8~-?`^uf9^NuKRNGs zch1i2&Ux1yid@uO?u(5odsh5V}k?I)7L?h7M?SOA2ycncMScou@vnC*=(@PSbSOpu&~7EOaKeZAY&=o2jxKq z3rl=21h%Wf(iBIyXdnEfH#nfveRP72rDz`%85t}yHrQB-_JIaBSXknV5`cweu+b6i zgPelF!qS9@R|@RwH$Eui>`OXz#rQ#DcZ+A!UtGb z+Un{ZM(_o()zv$i;D_y=i1tC9qQNqj_zW9hVQH(YXEWrFZFJt}?))(6$XMFy>K%vh zw>FldeNYlJ zMf;!*(_k4(TXelc8oo=~qU#;m@WaMZv=7QQ4VJOAwb(n{;SXXgMf>0=r@=B~LyV

lJe%M%w_OX;7U}0%1x3}l%4`M7u`=I>PU}0%1 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

1ygW!x&DdM!O!5_&EY=N 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 literal 0 HcmV?d00001 diff --git a/audits/062_riskFundShortfall_peckshield_20230825.pdf b/audits/062_riskFundShortfall_peckshield_20230825.pdf new file mode 100644 index 0000000000000000000000000000000000000000..83ed7acfba67e9fa473c31e9de453249ddf66e61 GIT binary patch literal 386716 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

Sxpx9$d)TMzu}!_Y;z;! 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

{&soY9#W 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 a-E^>kk!_21qh9G^ku4&Abos< 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

t1p=XP+pFWGWf%$7G)2IIS%y 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≫G0%Ha3_Bpkb9p#OMZYj&I0P8Gq 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 Date: Sat, 19 Aug 2023 23:07:44 +0300 Subject: [PATCH 28/39] chore: use SwapRouter from the core pool --- deploy/004-swap-router.ts | 4 +++- hardhat.config.ts | 5 ++++- package.json | 2 +- yarn.lock | 12 +++++++----- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/deploy/004-swap-router.ts b/deploy/004-swap-router.ts index 420886e44..f97042dc4 100644 --- a/deploy/004-swap-router.ts +++ b/deploy/004-swap-router.ts @@ -1,5 +1,7 @@ -import deploySwapRouter from "@venusprotocol/venus-protocol/deploy/005-deploy-swaprouter"; +import deploySwapRouter from "@venusprotocol/venus-protocol/dist/deploy/006-deploy-swaprouter"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; deploySwapRouter.tags = ["SwapRouter", "il"]; +deploySwapRouter.skip = async (hre: HardhatRuntimeEnvironment) => hre.network.live; export default deploySwapRouter; diff --git a/hardhat.config.ts b/hardhat.config.ts index 64ef887ec..fab617eaf 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -229,7 +229,10 @@ const config: HardhatUserConfig = { }, ], deployments: { - bsctestnet: ["node_modules/@venusprotocol/oracle/deployments/bsctestnet"], + bsctestnet: [ + "node_modules/@venusprotocol/oracle/deployments/bsctestnet", + "node_modules/@venusprotocol/venus-protocol/deployments/bsctestnet", + ], }, }, }; diff --git a/package.json b/package.json index 926d731ff..3d6ccce6c 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@typescript-eslint/parser": "^5.27.1", "@venusprotocol/governance-contracts": "^1.0.0", "@venusprotocol/oracle": "1.7.2", - "@venusprotocol/venus-protocol": "^0.6.0", + "@venusprotocol/venus-protocol": "3.0.0-dev.16", "bignumber.js": "9.0.0", "chai": "^4.3.6", "dotenv": "^10.0.0", diff --git a/yarn.lock b/yarn.lock index 07c804a9c..b96f798a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2966,7 +2966,7 @@ __metadata: "@typescript-eslint/parser": ^5.27.1 "@venusprotocol/governance-contracts": ^1.0.0 "@venusprotocol/oracle": 1.7.2 - "@venusprotocol/venus-protocol": ^0.6.0 + "@venusprotocol/venus-protocol": 3.0.0-dev.16 bignumber.js: 9.0.0 chai: ^4.3.6 dotenv: ^10.0.0 @@ -3028,15 +3028,17 @@ __metadata: languageName: node linkType: hard -"@venusprotocol/venus-protocol@npm:^0.6.0": - version: 0.6.0 - resolution: "@venusprotocol/venus-protocol@npm:0.6.0" +"@venusprotocol/venus-protocol@npm:3.0.0-dev.16": + version: 3.0.0-dev.16 + resolution: "@venusprotocol/venus-protocol@npm:3.0.0-dev.16" dependencies: + "@openzeppelin/contracts": ^4.8.3 "@openzeppelin/contracts-upgradeable": ^4.8.0 dotenv: ^16.0.1 + module-alias: ^2.2.2 peerDependencies: hardhat: ^2.10.1 - checksum: e05bf173d0320560b64bda12dfc32c1d2c205dd997ea1ca327d91e3b78dc03094f4a81bab4a84499c780d599e1574f70370becad0b3abb5b563d4154ba91668a + checksum: f20528a962c73f27725a09006798961f3994da274493fbfa4ac4c2caa0550908e65b4b2ae8e6dec8887a00c745db06a4b400cf7fdb837a23a4f5c26ce9d5ac31 languageName: node linkType: hard From d5e59872f34d8b2912d41296bb0c72f919042002 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Sun, 20 Aug 2023 00:04:27 +0300 Subject: [PATCH 29/39] chore: add mainnet config to hardhat --- hardhat.config.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index fab617eaf..4f870be36 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -162,9 +162,12 @@ const config: HardhatUserConfig = { chainId: 97, live: true, gasPrice: 20000000000, - accounts: { - mnemonic: process.env.MNEMONIC || "", - }, + accounts: process.env.TESTNET_PRIVATE_KEY ? [process.env.TESTNET_PRIVATE_KEY] : [], + }, + bscmainnet: { + url: "http://127.0.0.1:1248", + chainId: 56, + timeout: 1200000, }, bscmainnet: { url: "https://bsc-dataseed.binance.org/", From 62f4335881ea4eca1873ace81e639d5b3c7f5041 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Sun, 20 Aug 2023 00:05:25 +0300 Subject: [PATCH 30/39] chore: update deployment scripts for RiskFund, Shortfall, PSR --- deploy/014-riskfund-protocolshare.ts | 107 ++++++++++--------------- deploy/015-funds-config.ts | 51 ++++++++++++ deploy/015-transfer-funds-ownership.ts | 41 ---------- 3 files changed, 92 insertions(+), 107 deletions(-) create mode 100644 deploy/015-funds-config.ts delete mode 100644 deploy/015-transfer-funds-ownership.ts diff --git a/deploy/014-riskfund-protocolshare.ts b/deploy/014-riskfund-protocolshare.ts index 8fa61ec2e..0efb88b05 100644 --- a/deploy/014-riskfund-protocolshare.ts +++ b/deploy/014-riskfund-protocolshare.ts @@ -1,75 +1,29 @@ -import * as ERC20 from "@openzeppelin/contracts/build/contracts/ERC20.json"; -import { Contract } from "ethers"; import { ethers } from "hardhat"; import { DeployFunction } from "hardhat-deploy/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { getConfig, getTokenConfig } from "../helpers/deploymentConfig"; +import { getConfig } from "../helpers/deploymentConfig"; +import { getUnderlyingToken, toAddress } from "../helpers/deploymentUtils"; import { convertToUnit } from "../helpers/utils"; const MIN_AMOUNT_TO_CONVERT = convertToUnit(10, 18); const MIN_POOL_BAD_DEBT = convertToUnit(1000, 18); const maxLoopsLimit = 100; -const getAllMarkets = async (poolRegistry: Contract): Promise => { - const pools = await poolRegistry.getAllPools(); - const markets = await Promise.all( - pools.map(async ({ comptroller }: { comptroller: string }): Promise => { - const poolComptroller = await ethers.getContractAt("Comptroller", comptroller); - const vTokenAddresses = await poolComptroller.getAllMarkets(); - const vTokens = await Promise.all( - vTokenAddresses.map((vTokenAddress: string) => ethers.getContractAt("VToken", vTokenAddress)), - ); - return vTokens; - }), - ); - return markets.flat(); -}; - -const configureVToken = async (vToken: Contract, shortfallAddress: string, protocolShareReserveAddress: string) => { - console.log("Setting shortfall contract for vToken: ", vToken.address); - const tx1 = await vToken.setShortfallContract(shortfallAddress); - await tx1.wait(); - console.log("Setting protocol share reserve for vToken: ", vToken.address); - const tx2 = await vToken.setProtocolShareReserve(protocolShareReserveAddress); - await tx2.wait(); - console.log("Finished configuring vToken: ", vToken.address); -}; - -type AcmAddresses = { - bsctestnet: string; - bscmainnet: string; -}; - -const acmAddresses: AcmAddresses = { - bsctestnet: "0x45f8a08F534f34A97187626E05d4b6648Eeaa9AA", - bscmainnet: "0x4788629ABc6cFCA10F9f969efdEAa1cF70c23555", -}; - const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { tokensConfig } = await getConfig(hre.network.name); - const busdConfig = getTokenConfig("BUSD", tokensConfig); - - let BUSD; - if (busdConfig.isMock) { - BUSD = await ethers.getContract("MockBUSD"); - } else { - BUSD = await ethers.getContractAt(ERC20.abi, busdConfig.tokenAddress); - } + const { tokensConfig, preconfiguredAddresses } = await getConfig(hre.network.name); + const usdt = await getUnderlyingToken("USDT", tokensConfig); const poolRegistry = await ethers.getContract("PoolRegistry"); const deployerSigner = ethers.provider.getSigner(deployer); - const swapRouter = await ethers.getContract("SwapRouter"); - let accessControl; - if (hre.network.live) { - const networkName = hre.network.name === "bscmainnet" ? "bscmainnet" : "bsctestnet"; - accessControl = await ethers.getContractAt("AccessControlManager", acmAddresses[networkName]); - } else { - accessControl = await ethers.getContract("AccessControlManager"); - } + const swapRouterAddress = await toAddress(preconfiguredAddresses.SwapRouter_CorePool || "SwapRouter", hre); + const accessControlManagerAddress = await toAddress( + preconfiguredAddresses.AccessControlManager || "AccessControlManager", + hre, + ); const proxyAdmin = await ethers.getContract("DefaultProxyAdmin"); const owner = await proxyAdmin.owner(); @@ -81,7 +35,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { proxyContract: "OpenZeppelinTransparentProxy", execute: { methodName: "initialize", - args: [swapRouter.address, MIN_AMOUNT_TO_CONVERT, BUSD.address, accessControl.address, maxLoopsLimit], + args: [swapRouterAddress, MIN_AMOUNT_TO_CONVERT, usdt.address, accessControlManagerAddress, maxLoopsLimit], }, upgradeIndex: 0, }, @@ -99,7 +53,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { proxyContract: "OpenZeppelinTransparentProxy", execute: { methodName: "initialize", - args: [riskFund.address, MIN_POOL_BAD_DEBT, accessControl.address], + args: [riskFund.address, MIN_POOL_BAD_DEBT, accessControlManagerAddress], }, upgradeIndex: 0, }, @@ -108,13 +62,20 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { }); const shortfall = await ethers.getContract("Shortfall"); - const tx1 = await shortfall.connect(deployerSigner).updatePoolRegistry(poolRegistry.address); - await tx1.wait(); + if ((await shortfall.poolRegistry()) !== poolRegistry.address) { + console.log("Setting PoolRegistry address in Shortfall contract"); + const tx = await shortfall.connect(deployerSigner).updatePoolRegistry(poolRegistry.address); + await tx.wait(); + } - const tx2 = await riskFund.setShortfallContractAddress(shortfallDeployment.address); - await tx2.wait(1); + if ((await riskFund.shortfall()) !== shortfall.address) { + console.log("Setting Shortfall contract address in RiskFund"); + const tx = await riskFund.setShortfallContractAddress(shortfallDeployment.address); + await tx.wait(1); + } - const protocolShareReserveDeployment = await deploy("ProtocolShareReserve", { + const protocolIncomeReceiver = await toAddress(preconfiguredAddresses.VTreasury, hre); + await deploy("ProtocolShareReserve", { from: deployer, contract: "ProtocolShareReserve", proxy: { @@ -122,7 +83,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { proxyContract: "OpenZeppelinTransparentProxy", execute: { methodName: "initialize", - args: [deployer, riskFund.address], + args: [protocolIncomeReceiver, riskFund.address], }, upgradeIndex: 0, }, @@ -130,9 +91,23 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { log: true, }); - const allMarkets = await getAllMarkets(poolRegistry); - for (const market of allMarkets) { - await configureVToken(market, shortfallDeployment.address, protocolShareReserveDeployment.address); + for (const contractName of ["ProtocolShareReserve", "RiskFund"]) { + const contract = await ethers.getContract(contractName); + if ((await contract.poolRegistry()) !== poolRegistry.address) { + console.log(`Setting PoolRegistry address in ${contractName} contract`); + const tx = await contract.setPoolRegistry(poolRegistry.address); + await tx.wait(); + } + } + + const targetOwner = preconfiguredAddresses.NormalTimelock || deployer; + for (const contractName of ["RiskFund", "Shortfall", "ProtocolShareReserve"]) { + const contract = await ethers.getContract(contractName); + if ((await contract.owner()) !== targetOwner && (await contract.pendingOwner()) !== targetOwner) { + console.log(`Transferring ownership of ${contractName} to ${targetOwner}`); + const tx = await contract.transferOwnership(targetOwner); + await tx.wait(); + } } }; func.tags = ["RiskFund", "il"]; diff --git a/deploy/015-funds-config.ts b/deploy/015-funds-config.ts new file mode 100644 index 000000000..411c699d5 --- /dev/null +++ b/deploy/015-funds-config.ts @@ -0,0 +1,51 @@ +import { ethers } from "hardhat"; +import { DeployFunction } from "hardhat-deploy/types"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +import { PoolRegistry, VToken } from "../typechain"; + +const getAllMarkets = async (poolRegistry: PoolRegistry): Promise => { + const pools = await poolRegistry.getAllPools(); + const markets = await Promise.all( + pools.map(async ({ comptroller }: { comptroller: string }): Promise => { + const poolComptroller = await ethers.getContractAt("Comptroller", comptroller); + const vTokenAddresses = await poolComptroller.getAllMarkets(); + const vTokens = await Promise.all( + vTokenAddresses.map((vTokenAddress: string) => ethers.getContractAt("VToken", vTokenAddress)), + ); + return vTokens; + }), + ); + return markets.flat(); +}; + +const setShortfallAddress = async (vToken: VToken, shortfallAddress: string) => { + if ((await vToken.shortfall()) !== shortfallAddress) { + const tx = await vToken.setShortfallContract(shortfallAddress); + await tx.wait(); + } +}; + +const setProtocolShareReserveAddress = async (vToken: VToken, protocolShareReserveAddress: string) => { + if ((await vToken.protocolShareReserve()) !== protocolShareReserveAddress) { + const tx = await vToken.setProtocolShareReserve(protocolShareReserveAddress); + await tx.wait(); + } +}; + +const func: DeployFunction = async function (_: HardhatRuntimeEnvironment) { + const poolRegistry = await ethers.getContract("PoolRegistry"); + const vTokens = await getAllMarkets(poolRegistry); + const protocolShareReserve = await ethers.getContract("ProtocolShareReserve"); + const shortfall = await ethers.getContract("Shortfall"); + + for (const vToken of vTokens) { + await setShortfallAddress(vToken, shortfall.address); + await setProtocolShareReserveAddress(vToken, protocolShareReserve.address); + } +}; + +func.tags = ["FundsConfig", "il"]; +func.skip = async (hre: HardhatRuntimeEnvironment) => hre.network.live; + +export default func; diff --git a/deploy/015-transfer-funds-ownership.ts b/deploy/015-transfer-funds-ownership.ts deleted file mode 100644 index 5969e1130..000000000 --- a/deploy/015-transfer-funds-ownership.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ethers } from "hardhat"; -import { DeployFunction } from "hardhat-deploy/types"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; - -interface Config { - [key: string]: string; -} - -const targetOwners: Config = { - hardhat: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", // signer[1] from hardhat mnemonic - bsctestnet: "0xFA747c4a62c4D168276329F822d004026A1c05E9", // signer[1] from testnet mnemonic - mainnet: "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396", // NORMAL VIP Timelock -}; - -const contracts = ["RiskFund", "Shortfall", "ProtocolShareReserve"]; - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - await transfer2StepOwnerships(contracts, hre.network.name); -}; - -const transfer2StepOwnerships = async (contractNames: string[], networkName: string) => { - for (const contractName of contractNames) { - const contract = await ethers.getContract(contractName); - const owner = await contract.owner(); - - let tx; - if (owner !== targetOwners[networkName]) { - tx = await contract.transferOwnership(targetOwners[networkName]); - await tx.wait(1); - const pendingOwner = await contract.pendingOwner(); - console.log( - `${contractName} owner ${owner} sucessfully changed to ${pendingOwner}. Please accept the ownership.`, - ); - } else { - console.error(`${contractName} owner ${owner} is equal to target ownership address ${targetOwners[networkName]}`); - } - } -}; - -func.tags = ["TransferFundsOwnership"]; -export default func; From 96a684fb80775b82a0ea02c2afc383fb032a7c09 Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Wed, 23 Aug 2023 18:26:40 +0200 Subject: [PATCH 31/39] feat: set needed dependency to allow the deployment of SwapRouter --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 3d6ccce6c..a740fe2db 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@typescript-eslint/parser": "^5.27.1", "@venusprotocol/governance-contracts": "^1.0.0", "@venusprotocol/oracle": "1.7.2", - "@venusprotocol/venus-protocol": "3.0.0-dev.16", + "@venusprotocol/venus-protocol": "3.0.0-dev.18", "bignumber.js": "9.0.0", "chai": "^4.3.6", "dotenv": "^10.0.0", diff --git a/yarn.lock b/yarn.lock index b96f798a3..058ca9408 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2966,7 +2966,7 @@ __metadata: "@typescript-eslint/parser": ^5.27.1 "@venusprotocol/governance-contracts": ^1.0.0 "@venusprotocol/oracle": 1.7.2 - "@venusprotocol/venus-protocol": 3.0.0-dev.16 + "@venusprotocol/venus-protocol": 3.0.0-dev.18 bignumber.js: 9.0.0 chai: ^4.3.6 dotenv: ^10.0.0 @@ -3028,9 +3028,9 @@ __metadata: languageName: node linkType: hard -"@venusprotocol/venus-protocol@npm:3.0.0-dev.16": - version: 3.0.0-dev.16 - resolution: "@venusprotocol/venus-protocol@npm:3.0.0-dev.16" +"@venusprotocol/venus-protocol@npm:3.0.0-dev.18": + version: 3.0.0-dev.18 + resolution: "@venusprotocol/venus-protocol@npm:3.0.0-dev.18" dependencies: "@openzeppelin/contracts": ^4.8.3 "@openzeppelin/contracts-upgradeable": ^4.8.0 @@ -3038,7 +3038,7 @@ __metadata: module-alias: ^2.2.2 peerDependencies: hardhat: ^2.10.1 - checksum: f20528a962c73f27725a09006798961f3994da274493fbfa4ac4c2caa0550908e65b4b2ae8e6dec8887a00c745db06a4b400cf7fdb837a23a4f5c26ce9d5ac31 + checksum: 1545bba019602a9072474809461a9a20cbb465b108b0567716891ee5c4d457fa56eb14919bfce58fa314b0e21e7857a1375670f96161e0e7e2d2c1422ffff3e1 languageName: node linkType: hard From 94b0389d0cb944c9898689a6306c45c221033950 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Tue, 12 Sep 2023 10:09:17 +0300 Subject: [PATCH 32/39] chore: fix wrong USDT token symbol & add swap router --- helpers/deploymentConfig.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index 898b2d00a..63c80a843 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -86,7 +86,7 @@ const preconfiguredAddresses = { VTreasury: "account:deployer", }, bsctestnet: { - VTreasury: "0x8b293600c50d6fbdc6ed4251cc75ece29880276f", + VTreasury: "0x8b293600C50D6fbdc6Ed4251cc75ECe29880276f", NormalTimelock: "0xce10739590001705F7FF231611ba4A48B2820327", FastTrackTimelock: "0x3CFf21b7AF8390fE68799D58727d3b4C25a83cb6", CriticalTimelock: "0x23B893a7C45a5Eb8c8C062b9F32d0D2e43eD286D", @@ -95,6 +95,7 @@ const preconfiguredAddresses = { PancakeFactory: "0x182859893230dC89b114d6e2D547BFFE30474a21", WBNB: "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", VBNB_CorePool: "0x2E7222e51c0f6e98610A1543Aa3836E092CDe62c", + SwapRouter_CorePool: "0x83edf1deE1B730b7e8e13C00ba76027D63a51ac0", }, bscmainnet: { VTreasury: "0xF322942f644A996A617BD29c16bd7d231d9F35E9", @@ -106,6 +107,7 @@ const preconfiguredAddresses = { PancakeFactory: "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73", WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", VBNB_CorePool: "0xA07c5b74C9B40447a954e1466938b865b6BBea36", + SwapRouter_CorePool: "0x8938E6dA30b59c1E27d5f70a94688A89F7c815a4", }, }; @@ -201,7 +203,7 @@ export const globalConfig: NetworkConfig = { }, { isMock: true, - name: "Tether", + name: "Binance-Peg BSC-USD", symbol: "USDT", decimals: 18, tokenAddress: ethers.constants.AddressZero, @@ -1245,7 +1247,7 @@ export const globalConfig: NetworkConfig = { { isMock: false, name: "Binance-Peg BSC-USD", - symbol: "BUSD", + symbol: "USDT", decimals: 18, tokenAddress: "0x55d398326f99059fF775485246999027B3197955", }, From e9507464d68f59165f70b0d3cbe3b484c2b6a13b Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Tue, 12 Sep 2023 10:09:55 +0300 Subject: [PATCH 33/39] chore: remove duplicate bscmainnet entry --- hardhat.config.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 4f870be36..295f3e671 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -169,14 +169,6 @@ const config: HardhatUserConfig = { chainId: 56, timeout: 1200000, }, - bscmainnet: { - url: "https://bsc-dataseed.binance.org/", - chainId: 56, - live: true, - accounts: { - mnemonic: process.env.MNEMONIC || "", - }, - }, }, gasReporter: { enabled: process.env.REPORT_GAS !== undefined, From 93408b18da5a390869aab251354789910416c80e Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Tue, 12 Sep 2023 10:11:29 +0300 Subject: [PATCH 34/39] feat: deploy PSR, RiskFund, Shortfall --- deployments/bscmainnet.json | 6608 +++- .../bscmainnet/ProtocolShareReserve.json | 643 + .../ProtocolShareReserve_Implementation.json | 711 + .../ProtocolShareReserve_Proxy.json | 257 + deployments/bscmainnet/RiskFund.json | 1037 + .../bscmainnet/RiskFund_Implementation.json | 1256 + deployments/bscmainnet/RiskFund_Proxy.json | 277 + deployments/bscmainnet/Shortfall.json | 1192 + .../bscmainnet/Shortfall_Implementation.json | 1641 + deployments/bscmainnet/Shortfall_Proxy.json | 267 + .../394b060e0e484d4aa39aea929deecf07.json | 210 + deployments/bsctestnet.json | 32041 +++++++++++----- .../bsctestnet/ProtocolShareReserve.json | 643 + .../ProtocolShareReserve_Implementation.json | 711 + .../ProtocolShareReserve_Proxy.json | 257 + deployments/bsctestnet/RiskFund.json | 1037 + .../bsctestnet/RiskFund_Implementation.json | 1256 + deployments/bsctestnet/RiskFund_Proxy.json | 277 + deployments/bsctestnet/Shortfall.json | 1192 + .../bsctestnet/Shortfall_Implementation.json | 1641 + deployments/bsctestnet/Shortfall_Proxy.json | 267 + .../394b060e0e484d4aa39aea929deecf07.json | 210 + 22 files changed, 42352 insertions(+), 11279 deletions(-) create mode 100644 deployments/bscmainnet/ProtocolShareReserve.json create mode 100644 deployments/bscmainnet/ProtocolShareReserve_Implementation.json create mode 100644 deployments/bscmainnet/ProtocolShareReserve_Proxy.json create mode 100644 deployments/bscmainnet/RiskFund.json create mode 100644 deployments/bscmainnet/RiskFund_Implementation.json create mode 100644 deployments/bscmainnet/RiskFund_Proxy.json create mode 100644 deployments/bscmainnet/Shortfall.json create mode 100644 deployments/bscmainnet/Shortfall_Implementation.json create mode 100644 deployments/bscmainnet/Shortfall_Proxy.json create mode 100644 deployments/bscmainnet/solcInputs/394b060e0e484d4aa39aea929deecf07.json create mode 100644 deployments/bsctestnet/ProtocolShareReserve.json create mode 100644 deployments/bsctestnet/ProtocolShareReserve_Implementation.json create mode 100644 deployments/bsctestnet/ProtocolShareReserve_Proxy.json create mode 100644 deployments/bsctestnet/RiskFund.json create mode 100644 deployments/bsctestnet/RiskFund_Implementation.json create mode 100644 deployments/bsctestnet/RiskFund_Proxy.json create mode 100644 deployments/bsctestnet/Shortfall.json create mode 100644 deployments/bsctestnet/Shortfall_Implementation.json create mode 100644 deployments/bsctestnet/Shortfall_Proxy.json create mode 100644 deployments/bsctestnet/solcInputs/394b060e0e484d4aa39aea929deecf07.json diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index 36fbc5c45..32cff70ff 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -110,7 +110,7 @@ ] }, "ComptrollerImpl": { - "address": "0x939C05e2E694db68cE54d80bf29926b09190aA0F", + "address": "0x17a6ac4f7f01387303deB1D78f01aC0A0C1a75b0", "abi": [ { "inputs": [ @@ -657,6 +657,12 @@ "internalType": "address", "name": "rewardsDistributor", "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" } ], "name": "NewRewardsDistributor", @@ -6545,143 +6551,160 @@ } ] }, - "RewardsDistributorImpl": { - "address": "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", + "ProtocolShareReserve": { + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", "abi": [ { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "loopsLimit", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" }, { - "internalType": "uint256", - "name": "requiredLoops", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "name": "MaxLoopsLimitExceeded", - "type": "error" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "sender", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "calledContract", + "name": "implementation", "type": "address" - }, + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "internalType": "address", + "name": "admin_", + "type": "address" } ], - "name": "Unauthorized", - "type": "error" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "vToken", + "name": "newAdmin", "type": "address" - }, + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ { - "indexed": false, - "internalType": "uint32", - "name": "newBlock", - "type": "uint32" + "internalType": "address", + "name": "implementation_", + "type": "address" } ], - "name": "BorrowLastRewardingBlockUpdated", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "contributor", + "name": "newImplementation", "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newSpeed", - "type": "uint256" } ], - "name": "ContributorRewardTokenSpeedUpdated", - "type": "event" + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "contributor", + "name": "newImplementation", "type": "address" }, { - "indexed": false, - "internalType": "uint256", - "name": "rewardAccrued", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "ContributorRewardsUpdated", - "type": "event" + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, - "internalType": "contract VToken", - "name": "vToken", + "internalType": "address", + "name": "comptroller", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "borrower", + "name": "asset", "type": "address" }, { "indexed": false, "internalType": "uint256", - "name": "rewardTokenDelta", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewardTokenTotal", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewardTokenBorrowIndex", + "name": "amount", "type": "uint256" } ], - "name": "DistributedBorrowerRewardToken", + "name": "AssetsReservesUpdated", "type": "event" }, { @@ -6689,36 +6712,24 @@ "inputs": [ { "indexed": true, - "internalType": "contract VToken", - "name": "vToken", + "internalType": "address", + "name": "comptroller", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "supplier", + "name": "asset", "type": "address" }, { "indexed": false, "internalType": "uint256", - "name": "rewardTokenDelta", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewardTokenTotal", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewardTokenSupplyIndex", + "name": "amount", "type": "uint256" } ], - "name": "DistributedSupplierRewardToken", + "name": "FundsReleased", "type": "event" }, { @@ -6740,49 +6751,17 @@ { "indexed": true, "internalType": "address", - "name": "vToken", - "type": "address" - } - ], - "name": "MarketInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldMaxLoopsLimit", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newmaxLoopsLimit", - "type": "uint256" - } - ], - "name": "MaxLoopsLimitUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "oldAccessControlManager", + "name": "previousOwner", "type": "address" }, { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "newAccessControlManager", + "name": "newOwner", "type": "address" } ], - "name": "NewAccessControlManager", + "name": "OwnershipTransferStarted", "type": "event" }, { @@ -6801,7 +6780,7 @@ "type": "address" } ], - "name": "OwnershipTransferStarted", + "name": "OwnershipTransferred", "type": "event" }, { @@ -6810,17 +6789,17 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "oldPoolRegistry", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "newPoolRegistry", "type": "address" } ], - "name": "OwnershipTransferred", + "name": "PoolRegistryUpdated", "type": "event" }, { @@ -6829,123 +6808,101 @@ { "indexed": true, "internalType": "address", - "name": "vToken", + "name": "token", "type": "address" }, - { - "components": [ - { - "internalType": "uint256", - "name": "mantissa", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ExponentialNoError.Exp", - "name": "marketBorrowIndex", - "type": "tuple" - } - ], - "name": "RewardTokenBorrowIndexUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ { "indexed": true, - "internalType": "contract VToken", - "name": "vToken", + "internalType": "address", + "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", - "name": "newSpeed", + "name": "amount", "type": "uint256" } ], - "name": "RewardTokenBorrowSpeedUpdated", + "name": "SweepToken", "type": "event" }, { - "anonymous": false, + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [ { - "indexed": true, "internalType": "address", - "name": "recipient", + "name": "", "type": "address" - }, + } + ], + "name": "assetsReserves", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "amount", + "name": "", "type": "uint256" } ], - "name": "RewardTokenGranted", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "vToken", + "name": "comptroller", "type": "address" - } - ], - "name": "RewardTokenSupplyIndexUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, - "internalType": "contract VToken", - "name": "vToken", + "internalType": "address", + "name": "asset", "type": "address" - }, + } + ], + "name": "getPoolAssetReserve", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "newSpeed", + "name": "", "type": "uint256" } ], - "name": "RewardTokenSupplySpeedUpdated", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "vToken", + "name": "protocolIncome_", "type": "address" }, { - "indexed": false, - "internalType": "uint32", - "name": "newBlock", - "type": "uint32" + "internalType": "address", + "name": "riskFund_", + "type": "address" } ], - "name": "SupplyLastRewardingBlockUpdated", - "type": "event" + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "INITIAL_INDEX", + "name": "owner", "outputs": [ { - "internalType": "uint224", + "internalType": "address", "name": "", - "type": "uint224" + "type": "address" } ], "stateMutability": "view", @@ -6953,17 +6910,10 @@ }, { "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "accessControlManager", + "name": "pendingOwner", "outputs": [ { - "internalType": "contract IAccessControlManagerV8", + "internalType": "address", "name": "", "type": "address" } @@ -6972,92 +6922,75 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "poolRegistry", + "outputs": [ { "internalType": "address", - "name": "holder", + "name": "", "type": "address" - }, - { - "internalType": "contract VToken[]", - "name": "vTokens", - "type": "address[]" } ], - "name": "claimRewardToken", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "protocolIncome", + "outputs": [ { "internalType": "address", - "name": "holder", + "name": "", "type": "address" } ], - "name": "claimRewardToken", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "comptroller", "type": "address" }, { "internalType": "address", - "name": "borrower", + "name": "asset", "type": "address" }, { - "components": [ - { - "internalType": "uint256", - "name": "mantissa", - "type": "uint256" - } - ], - "internalType": "struct ExponentialNoError.Exp", - "name": "marketBorrowIndex", - "type": "tuple" + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "releaseFunds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "distributeBorrowerRewardToken", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "vToken", - "type": "address" - }, - { - "internalType": "address", - "name": "supplier", - "type": "address" - } - ], - "name": "distributeSupplierRewardToken", + "inputs": [], + "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "getBlockNumber", + "name": "riskFund", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", @@ -7067,16 +7000,11 @@ "inputs": [ { "internalType": "address", - "name": "recipient", + "name": "poolRegistry_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" } ], - "name": "grantRewardToken", + "name": "setPoolRegistry", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -7084,27 +7012,17 @@ { "inputs": [ { - "internalType": "contract Comptroller", - "name": "comptroller_", - "type": "address" - }, - { - "internalType": "contract IERC20Upgradeable", - "name": "rewardToken_", + "internalType": "address", + "name": "_token", "type": "address" }, - { - "internalType": "uint256", - "name": "loopsLimit_", - "type": "uint256" - }, { "internalType": "address", - "name": "accessControlManager_", + "name": "_to", "type": "address" } ], - "name": "initialize", + "name": "sweepToken", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -7113,11 +7031,11 @@ "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "newOwner", "type": "address" } ], - "name": "initializeMarket", + "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -7126,169 +7044,206 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" - } - ], - "name": "lastContributorBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxLoopsLimit", - "outputs": [ + }, { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "address", + "name": "asset", + "type": "address" } ], - "stateMutability": "view", + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "_logic", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + }, { "internalType": "address", - "name": "", + "name": "admin_", "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" - }, + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "ProtocolShareReserve_Implementation": { + "address": "0xc1c56732FcaFca0F66D59745Ec69DC642EC20ab8", + "abi": [ { "inputs": [], - "name": "renounceOwnership", - "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "constructor" }, { "inputs": [], - "name": "rewardToken", - "outputs": [ + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "contract IERC20Upgradeable", - "name": "", + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "AssetsReservesUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" - } - ], - "name": "rewardTokenAccrued", - "outputs": [ + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "amount", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "FundsReleased", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" } ], - "name": "rewardTokenBorrowSpeeds", - "outputs": [ + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "OwnershipTransferStarted", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", "type": "address" } ], - "name": "rewardTokenBorrowState", - "outputs": [ - { - "internalType": "uint224", - "name": "index", - "type": "uint224" - }, + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint32", - "name": "block", - "type": "uint32" + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" }, { - "internalType": "uint32", - "name": "lastRewardingBlock", - "type": "uint32" + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "PoolRegistryUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "token", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "", + "name": "to", "type": "address" - } - ], - "name": "rewardTokenBorrowerIndex", - "outputs": [ + }, { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "amount", "type": "uint256" } ], - "stateMutability": "view", + "name": "SweepToken", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { @@ -7299,7 +7254,7 @@ "type": "address" } ], - "name": "rewardTokenContributorSpeeds", + "name": "assetsReserves", "outputs": [ { "internalType": "uint256", @@ -7314,16 +7269,16 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" }, { "internalType": "address", - "name": "", + "name": "asset", "type": "address" } ], - "name": "rewardTokenSupplierIndex", + "name": "getPoolAssetReserve", "outputs": [ { "internalType": "uint256", @@ -7338,113 +7293,130 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "protocolIncome_", + "type": "address" + }, + { + "internalType": "address", + "name": "riskFund_", "type": "address" } ], - "name": "rewardTokenSupplySpeeds", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "pendingOwner", + "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], - "name": "rewardTokenSupplyState", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", "outputs": [ { - "internalType": "uint224", - "name": "index", - "type": "uint224" - }, - { - "internalType": "uint32", - "name": "block", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "lastRewardingBlock", - "type": "uint32" + "internalType": "address", + "name": "", + "type": "address" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "protocolIncome", + "outputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "", "type": "address" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "contributor", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", "type": "address" }, { "internalType": "uint256", - "name": "rewardTokenSpeed", + "name": "amount", "type": "uint256" } ], - "name": "setContributorRewardTokenSpeed", + "name": "releaseFunds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "contract VToken[]", - "name": "vTokens", - "type": "address[]" - }, - { - "internalType": "uint32[]", - "name": "supplyLastRewardingBlocks", - "type": "uint32[]" - }, + "inputs": [], + "name": "riskFund", + "outputs": [ { - "internalType": "uint32[]", - "name": "borrowLastRewardingBlocks", - "type": "uint32[]" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "setLastRewardingBlocks", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "limit", - "type": "uint256" + "internalType": "address", + "name": "poolRegistry_", + "type": "address" } ], - "name": "setMaxLoopsLimit", + "name": "setPoolRegistry", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -7452,22 +7424,17 @@ { "inputs": [ { - "internalType": "contract VToken[]", - "name": "vTokens", - "type": "address[]" + "internalType": "address", + "name": "_token", + "type": "address" }, { - "internalType": "uint256[]", - "name": "supplySpeeds", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "borrowSpeeds", - "type": "uint256[]" + "internalType": "address", + "name": "_to", + "type": "address" } ], - "name": "setRewardTokenSpeeds", + "name": "sweepToken", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -7489,58 +7456,46 @@ "inputs": [ { "internalType": "address", - "name": "contributor", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", "type": "address" } ], - "name": "updateContributorRewards", + "name": "updateAssetsState", "outputs": [], "stateMutability": "nonpayable", "type": "function" - }, + } + ] + }, + "ProtocolShareReserve_Proxy": { + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "_logic", "type": "address" }, - { - "components": [ - { - "internalType": "uint256", - "name": "mantissa", - "type": "uint256" - } - ], - "internalType": "struct ExponentialNoError.Exp", - "name": "marketBorrowIndex", - "type": "tuple" - } - ], - "name": "updateRewardTokenBorrowIndex", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "admin_", "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" } ], - "name": "updateRewardTokenSupplyIndex", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ] - }, - "RewardsDistributor_DeFi_0": { - "address": "0x7524116CEC937ef17B5998436F16d1306c4F7EF8", - "abi": [ + "stateMutability": "payable", + "type": "constructor" + }, { "anonymous": false, "inputs": [ @@ -7663,6 +7618,16 @@ { "stateMutability": "payable", "type": "receive" + } + ] + }, + "RewardsDistributorImpl": { + "address": "0x01251D4eF6bb9f56C8Bef7D3A201f00f4C122589", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" }, { "inputs": [ @@ -8646,181 +8611,11 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" } ] }, - "RewardsDistributor_DeFi_0_Proxy": { + "RewardsDistributor_DeFi_0": { "address": "0x7524116CEC937ef17B5998436F16d1306c4F7EF8", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "admin_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "implementation_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "RewardsDistributor_DeFi_1": { - "address": "0x14d9A428D0f35f81A30ca8D8b2F3974D3CccB98B", "abi": [ { "anonymous": false, @@ -9951,8 +9746,8 @@ } ] }, - "RewardsDistributor_DeFi_1_Proxy": { - "address": "0x14d9A428D0f35f81A30ca8D8b2F3974D3CccB98B", + "RewardsDistributor_DeFi_0_Proxy": { + "address": "0x7524116CEC937ef17B5998436F16d1306c4F7EF8", "abi": [ { "inputs": [ @@ -10100,8 +9895,8 @@ } ] }, - "RewardsDistributor_GameFi_0": { - "address": "0x501a91b995Bd41177503A1A4144F3D25BFF869e1", + "RewardsDistributor_DeFi_1": { + "address": "0x14d9A428D0f35f81A30ca8D8b2F3974D3CccB98B", "abi": [ { "anonymous": false, @@ -11232,8 +11027,8 @@ } ] }, - "RewardsDistributor_GameFi_0_Proxy": { - "address": "0x501a91b995Bd41177503A1A4144F3D25BFF869e1", + "RewardsDistributor_DeFi_1_Proxy": { + "address": "0x14d9A428D0f35f81A30ca8D8b2F3974D3CccB98B", "abi": [ { "inputs": [ @@ -11381,8 +11176,8 @@ } ] }, - "RewardsDistributor_GameFi_1": { - "address": "0x2517A3bEe42EA8f628926849B04870260164b555", + "RewardsDistributor_GameFi_0": { + "address": "0x501a91b995Bd41177503A1A4144F3D25BFF869e1", "abi": [ { "anonymous": false, @@ -12513,8 +12308,8 @@ } ] }, - "RewardsDistributor_GameFi_1_Proxy": { - "address": "0x2517A3bEe42EA8f628926849B04870260164b555", + "RewardsDistributor_GameFi_0_Proxy": { + "address": "0x501a91b995Bd41177503A1A4144F3D25BFF869e1", "abi": [ { "inputs": [ @@ -12662,8 +12457,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_0": { - "address": "0x63aFCe42086c8302659CA0E21F4Eade27Ad85ded", + "RewardsDistributor_GameFi_1": { + "address": "0x2517A3bEe42EA8f628926849B04870260164b555", "abi": [ { "anonymous": false, @@ -13794,8 +13589,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_0_Proxy": { - "address": "0x63aFCe42086c8302659CA0E21F4Eade27Ad85ded", + "RewardsDistributor_GameFi_1_Proxy": { + "address": "0x2517A3bEe42EA8f628926849B04870260164b555", "abi": [ { "inputs": [ @@ -13943,8 +13738,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_1": { - "address": "0x79397BAc982718347406Ebb7A6a8845896fdD8dE", + "RewardsDistributor_LiquidStakedBNB_0": { + "address": "0x63aFCe42086c8302659CA0E21F4Eade27Ad85ded", "abi": [ { "anonymous": false, @@ -15075,8 +14870,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_1_Proxy": { - "address": "0x79397BAc982718347406Ebb7A6a8845896fdD8dE", + "RewardsDistributor_LiquidStakedBNB_0_Proxy": { + "address": "0x63aFCe42086c8302659CA0E21F4Eade27Ad85ded", "abi": [ { "inputs": [ @@ -15224,8 +15019,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_2": { - "address": "0x6a7b50EccC721f0Fa9FD7879A7dF082cdA60Db78", + "RewardsDistributor_LiquidStakedBNB_1": { + "address": "0x79397BAc982718347406Ebb7A6a8845896fdD8dE", "abi": [ { "anonymous": false, @@ -16356,8 +16151,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_2_Proxy": { - "address": "0x6a7b50EccC721f0Fa9FD7879A7dF082cdA60Db78", + "RewardsDistributor_LiquidStakedBNB_1_Proxy": { + "address": "0x79397BAc982718347406Ebb7A6a8845896fdD8dE", "abi": [ { "inputs": [ @@ -16505,8 +16300,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_3": { - "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "RewardsDistributor_LiquidStakedBNB_2": { + "address": "0x6a7b50EccC721f0Fa9FD7879A7dF082cdA60Db78", "abi": [ { "anonymous": false, @@ -17637,8 +17432,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_3_Proxy": { - "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", + "RewardsDistributor_LiquidStakedBNB_2_Proxy": { + "address": "0x6a7b50EccC721f0Fa9FD7879A7dF082cdA60Db78", "abi": [ { "inputs": [ @@ -17786,8 +17581,8 @@ } ] }, - "RewardsDistributor_Stablecoins_0": { - "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", + "RewardsDistributor_LiquidStakedBNB_3": { + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", "abi": [ { "anonymous": false, @@ -18918,8 +18713,8 @@ } ] }, - "RewardsDistributor_Stablecoins_0_Proxy": { - "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", + "RewardsDistributor_LiquidStakedBNB_3_Proxy": { + "address": "0xBE607b239a8776B47159e2b0E9E65a7F1DAA6478", "abi": [ { "inputs": [ @@ -19067,8 +18862,8 @@ } ] }, - "RewardsDistributor_Stablecoins_1": { - "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "RewardsDistributor_Stablecoins_0": { + "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", "abi": [ { "anonymous": false, @@ -20199,8 +19994,8 @@ } ] }, - "RewardsDistributor_Stablecoins_1_Proxy": { - "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", + "RewardsDistributor_Stablecoins_0_Proxy": { + "address": "0xBA711976CdF8CF3288bF721f758fB764503Eb1f6", "abi": [ { "inputs": [ @@ -20348,8 +20143,8 @@ } ] }, - "RewardsDistributor_Tron_0": { - "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", + "RewardsDistributor_Stablecoins_1": { + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", "abi": [ { "anonymous": false, @@ -21480,8 +21275,8 @@ } ] }, - "RewardsDistributor_Tron_0_Proxy": { - "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", + "RewardsDistributor_Stablecoins_1_Proxy": { + "address": "0xA31185D804BF9209347698128984a43A67Ce6d11", "abi": [ { "inputs": [ @@ -21629,8 +21424,8 @@ } ] }, - "RewardsDistributor_Tron_1": { - "address": "0x6536123503DF76BDfF8207e4Fb0C594Bc5eFD00A", + "RewardsDistributor_Tron_0": { + "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", "abi": [ { "anonymous": false, @@ -22761,8 +22556,8 @@ } ] }, - "RewardsDistributor_Tron_1_Proxy": { - "address": "0x6536123503DF76BDfF8207e4Fb0C594Bc5eFD00A", + "RewardsDistributor_Tron_0_Proxy": { + "address": "0x804F3893d3c1C3EFFDf778eDDa7C199129235882", "abi": [ { "inputs": [ @@ -22910,8 +22705,8 @@ } ] }, - "RewardsDistributor_Tron_2": { - "address": "0x22af8a65639a351a9D5d77d5a25ea5e1Cf5e9E6b", + "RewardsDistributor_Tron_1": { + "address": "0x6536123503DF76BDfF8207e4Fb0C594Bc5eFD00A", "abi": [ { "anonymous": false, @@ -24042,8 +23837,8 @@ } ] }, - "RewardsDistributor_Tron_2_Proxy": { - "address": "0x22af8a65639a351a9D5d77d5a25ea5e1Cf5e9E6b", + "RewardsDistributor_Tron_1_Proxy": { + "address": "0x6536123503DF76BDfF8207e4Fb0C594Bc5eFD00A", "abi": [ { "inputs": [ @@ -24191,8 +23986,8 @@ } ] }, - "RewardsDistributor_Tron_3": { - "address": "0x08e4AFd80A5849FDBa4bBeea86ed470D697e4C54", + "RewardsDistributor_Tron_2": { + "address": "0x22af8a65639a351a9D5d77d5a25ea5e1Cf5e9E6b", "abi": [ { "anonymous": false, @@ -25035,16 +24830,5191 @@ "inputs": [ { "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RewardsDistributor_Tron_2_Proxy": { + "address": "0x22af8a65639a351a9D5d77d5a25ea5e1Cf5e9E6b", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "RewardsDistributor_Tron_3": { + "address": "0x08e4AFd80A5849FDBa4bBeea86ed470D697e4C54", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RewardsDistributor_Tron_3_Proxy": { + "address": "0x08e4AFd80A5849FDBa4bBeea86ed470D697e4C54", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "RiskFund": { + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ApproveFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldConvertibleBaseAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newConvertibleBaseAsset", + "type": "address" + } + ], + "name": "ConvertibleBaseAssetUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinAmountToConvert", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinAmountToConvert", + "type": "uint256" + } + ], + "name": "MinAmountToConvertUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPancakeSwapRouter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPancakeSwapRouter", + "type": "address" + } + ], + "name": "PancakeSwapRouterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldShortfallContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newShortfallContract", + "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + } + ], + "name": "SwappedPoolsAssets", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredReserveForAuction", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convertibleBaseAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "convertibleBaseAsset_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAmountToConvert", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pancakeSwapRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convertibleBaseAsset", + "type": "address" + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + } + ], + "name": "setMinAmountToConvert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + } + ], + "name": "setPancakeSwapRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "shortfallContractAddress_", + "type": "address" + } + ], + "name": "setShortfallContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "internalType": "address[][]", + "name": "paths", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapPoolsAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferReserveForAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RiskFund_Implementation": { + "address": "0x87ac8dD81Ec00D2183a04D22884e7FC67f6ce0C8", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ApproveFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldConvertibleBaseAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newConvertibleBaseAsset", + "type": "address" + } + ], + "name": "ConvertibleBaseAssetUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinAmountToConvert", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinAmountToConvert", + "type": "uint256" + } + ], + "name": "MinAmountToConvertUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPancakeSwapRouter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPancakeSwapRouter", + "type": "address" + } + ], + "name": "PancakeSwapRouterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldShortfallContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newShortfallContract", + "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + } + ], + "name": "SwappedPoolsAssets", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredReserveForAuction", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convertibleBaseAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "convertibleBaseAsset_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAmountToConvert", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pancakeSwapRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convertibleBaseAsset", + "type": "address" + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + } + ], + "name": "setMinAmountToConvert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + } + ], + "name": "setPancakeSwapRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "shortfallContractAddress_", + "type": "address" + } + ], + "name": "setShortfallContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "internalType": "address[][]", + "name": "paths", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapPoolsAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferReserveForAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "RiskFund_Proxy": { + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "Shortfall": { + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableBalance", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "owedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientDebt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFind", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketDebt", + "type": "uint256[]" + } + ], + "name": "AuctionClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "AuctionRestarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketsDebt", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "name": "AuctionStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "bidder", + "type": "address" + } + ], + "name": "BidPlaced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldIncentiveBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newIncentiveBps", + "type": "uint256" + } + ], + "name": "IncentiveBpsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinimumPoolBadDebt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "MinimumPoolBadDebtUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldNextBidderBlockLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newNextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "NextBidderBlockLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldWaitForFirstBidder", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWaitForFirstBidder", + "type": "uint256" + } + ], + "name": "WaitForFirstBidderUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "auctions", + "outputs": [ + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "internalType": "enum Shortfall.AuctionStatus", + "name": "status", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "highestBidBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "claimTokenDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "closeAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "incentiveBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IRiskFund", + "name": "riskFund_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minimumPoolBadDebt_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minimumPoolBadDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextBidderBlockLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "placeBid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "restartAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resumeAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "contract IRiskFund", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "startAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalTokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_incentiveBps", + "type": "uint256" + } + ], + "name": "updateIncentiveBps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "updateMinimumPoolBadDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "updateNextBidderBlockLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "updatePoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_waitForFirstBidder", + "type": "uint256" + } + ], + "name": "updateWaitForFirstBidder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "waitForFirstBidder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "Shortfall_Implementation": { + "address": "0x916e607AF3250ECB2Fd4ea82A37Eb2756A20e1fC", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableBalance", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "owedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientDebt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFind", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketDebt", + "type": "uint256[]" + } + ], + "name": "AuctionClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "AuctionRestarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketsDebt", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "name": "AuctionStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "bidder", + "type": "address" + } + ], + "name": "BidPlaced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldIncentiveBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newIncentiveBps", + "type": "uint256" + } + ], + "name": "IncentiveBpsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinimumPoolBadDebt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "MinimumPoolBadDebtUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldNextBidderBlockLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newNextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "NextBidderBlockLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldWaitForFirstBidder", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWaitForFirstBidder", + "type": "uint256" + } + ], + "name": "WaitForFirstBidderUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "auctions", + "outputs": [ + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "internalType": "enum Shortfall.AuctionStatus", + "name": "status", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "highestBidBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "claimTokenDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", "type": "address" } ], - "name": "rewardTokenBorrowerIndex", + "name": "closeAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "incentiveBps", "outputs": [ { "internalType": "uint256", @@ -25057,13 +30027,30 @@ }, { "inputs": [ + { + "internalType": "contract IRiskFund", + "name": "riskFund_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minimumPoolBadDebt_", + "type": "uint256" + }, { "internalType": "address", - "name": "", + "name": "accessControlManager_", "type": "address" } ], - "name": "rewardTokenContributorSpeeds", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minimumPoolBadDebt", "outputs": [ { "internalType": "uint256", @@ -25075,24 +30062,46 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "nextBidderBlockLimit", + "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" - }, + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], - "name": "rewardTokenSupplierIndex", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", @@ -25102,45 +30111,73 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" + }, + { + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" } ], - "name": "rewardTokenSupplySpeeds", + "name": "placeBid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" } ], - "name": "rewardTokenSupplyState", + "name": "restartAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resumeAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", "outputs": [ { - "internalType": "uint224", - "name": "index", - "type": "uint224" - }, - { - "internalType": "uint32", - "name": "block", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "lastRewardingBlock", - "type": "uint32" + "internalType": "contract IRiskFund", + "name": "", + "type": "address" } ], "stateMutability": "view", @@ -25163,16 +30200,11 @@ "inputs": [ { "internalType": "address", - "name": "contributor", + "name": "comptroller", "type": "address" - }, - { - "internalType": "uint256", - "name": "rewardTokenSpeed", - "type": "uint256" } ], - "name": "setContributorRewardTokenSpeed", + "name": "startAuction", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -25180,58 +30212,55 @@ { "inputs": [ { - "internalType": "contract VToken[]", - "name": "vTokens", - "type": "address[]" + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" }, { - "internalType": "uint32[]", - "name": "supplyLastRewardingBlocks", - "type": "uint32[]" - }, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDebt", + "outputs": [ { - "internalType": "uint32[]", - "name": "borrowLastRewardingBlocks", - "type": "uint32[]" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "setLastRewardingBlocks", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalTokenDebt", + "outputs": [ { "internalType": "uint256", - "name": "limit", + "name": "", "type": "uint256" } ], - "name": "setMaxLoopsLimit", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { - "internalType": "contract VToken[]", - "name": "vTokens", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "supplySpeeds", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "borrowSpeeds", - "type": "uint256[]" + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "setRewardTokenSpeeds", + "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -25239,12 +30268,12 @@ { "inputs": [ { - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "_incentiveBps", + "type": "uint256" } ], - "name": "transferOwnership", + "name": "updateIncentiveBps", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -25252,12 +30281,12 @@ { "inputs": [ { - "internalType": "address", - "name": "contributor", - "type": "address" + "internalType": "uint256", + "name": "_minimumPoolBadDebt", + "type": "uint256" } ], - "name": "updateContributorRewards", + "name": "updateMinimumPoolBadDebt", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -25265,24 +30294,12 @@ { "inputs": [ { - "internalType": "address", - "name": "vToken", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "mantissa", - "type": "uint256" - } - ], - "internalType": "struct ExponentialNoError.Exp", - "name": "marketBorrowIndex", - "type": "tuple" + "internalType": "uint256", + "name": "_nextBidderBlockLimit", + "type": "uint256" } ], - "name": "updateRewardTokenBorrowIndex", + "name": "updateNextBidderBlockLimit", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -25291,11 +30308,11 @@ "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "poolRegistry_", "type": "address" } ], - "name": "updateRewardTokenSupplyIndex", + "name": "updatePoolRegistry", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -25303,28 +30320,33 @@ { "inputs": [ { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" - }, + "internalType": "uint256", + "name": "_waitForFirstBidder", + "type": "uint256" + } + ], + "name": "updateWaitForFirstBidder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "waitForFirstBidder", + "outputs": [ { - "internalType": "bytes", - "name": "_data", - "type": "bytes" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "stateMutability": "view", + "type": "function" } ] }, - "RewardsDistributor_Tron_3_Proxy": { - "address": "0x08e4AFd80A5849FDBa4bBeea86ed470D697e4C54", + "Shortfall_Proxy": { + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", "abi": [ { "inputs": [ diff --git a/deployments/bscmainnet/ProtocolShareReserve.json b/deployments/bscmainnet/ProtocolShareReserve.json new file mode 100644 index 000000000..0c1fdc6be --- /dev/null +++ b/deployments/bscmainnet/ProtocolShareReserve.json @@ -0,0 +1,643 @@ +{ + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsReleased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "protocolIncome_", + "type": "address" + }, + { + "internalType": "address", + "name": "riskFund_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolIncome", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "releaseFunds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "transactionIndex": 111, + "gasUsed": "817682", + "logsBloom": "0x00000000010000000000000000000000400000000000000000800000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000002000001000000000000000000000000000000010000020000000000000000000800000000800000000000000000000000400001800000080000000000000000000000000000000080000000000000800000000000000000000000000000000400000000000000000000000000000002000000000020000000000000000000040000000000000400000000000000001020000000000000000000000000000000000000000000000000000000000000000100", + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112", + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "logs": [ + { + "transactionIndex": 111, + "blockNumber": 31670925, + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000c1c56732fcafca0f66d59745ec69dc642ec20ab8" + ], + "data": "0x", + "logIndex": 258, + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112" + }, + { + "transactionIndex": 111, + "blockNumber": 31670925, + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000055a9f5374af30e3045fb491f1da3c2e8a74d168d" + ], + "data": "0x", + "logIndex": 259, + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112" + }, + { + "transactionIndex": 111, + "blockNumber": 31670925, + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 260, + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112" + }, + { + "transactionIndex": 111, + "blockNumber": 31670925, + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 261, + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112" + } + ], + "blockNumber": 31670925, + "cumulativeGasUsed": "13118645", + "status": 1, + "byzantium": true + }, + "args": [ + "0xc1c56732FcaFca0F66D59745Ec69DC642EC20ab8", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0x485cc955000000000000000000000000f322942f644a996a617bd29c16bd7d231d9f35e9000000000000000000000000df31a28d68a2ab381d42b380649ead7ae2a76e42" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": ["0xF322942f644A996A617BD29c16bd7d231d9F35E9", "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42"] + }, + "implementation": "0xc1c56732FcaFca0F66D59745Ec69DC642EC20ab8", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bscmainnet/ProtocolShareReserve_Implementation.json b/deployments/bscmainnet/ProtocolShareReserve_Implementation.json new file mode 100644 index 000000000..b8203fb11 --- /dev/null +++ b/deployments/bscmainnet/ProtocolShareReserve_Implementation.json @@ -0,0 +1,711 @@ +{ + "address": "0xc1c56732FcaFca0F66D59745Ec69DC642EC20ab8", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsReleased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "protocolIncome_", + "type": "address" + }, + { + "internalType": "address", + "name": "riskFund_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolIncome", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "releaseFunds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xcae7176a7194c5a1374753b1283f725e3eaa770ce3967fb2fbc18d45c80b917d", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xc1c56732FcaFca0F66D59745Ec69DC642EC20ab8", + "transactionIndex": 74, + "gasUsed": "1213372", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000001000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000", + "blockHash": "0x38e50f3359ec0526f0a64abf1c0c3c793433e1a8c333a9f94d4fbb200bb394cd", + "transactionHash": "0xcae7176a7194c5a1374753b1283f725e3eaa770ce3967fb2fbc18d45c80b917d", + "logs": [ + { + "transactionIndex": 74, + "blockNumber": 31670920, + "transactionHash": "0xcae7176a7194c5a1374753b1283f725e3eaa770ce3967fb2fbc18d45c80b917d", + "address": "0xc1c56732FcaFca0F66D59745Ec69DC642EC20ab8", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 143, + "blockHash": "0x38e50f3359ec0526f0a64abf1c0c3c793433e1a8c333a9f94d4fbb200bb394cd" + } + ], + "blockNumber": 31670920, + "cumulativeGasUsed": "6522203", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "394b060e0e484d4aa39aea929deecf07", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AssetsReservesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsReleased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPoolRegistry\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPoolRegistry\",\"type\":\"address\"}],\"name\":\"PoolRegistryUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"SweepToken\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetsReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getPoolAssetReserve\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"protocolIncome_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"riskFund_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolIncome\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"releaseFunds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"riskFund\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"name\":\"setPoolRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sweepToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"updateAssetsState\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"getPoolAssetReserve(address,address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"asset\":\"Asset address.\",\"comptroller\":\"Comptroller address(pool).\"},\"returns\":{\"_0\":\"Asset's reserve in risk fund.\"}},\"initialize(address,address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when protocol income address is zeroZeroAddressNotAllowed is thrown when risk fund address is zero\",\"params\":{\"protocolIncome_\":\"The address protocol income will be sent to\",\"riskFund_\":\"Risk fund address\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"releaseFunds(address,address,uint256)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"amount\":\"Amount to release\",\"asset\":\"Asset to be released\",\"comptroller\":\"Pool's Comptroller\"},\"returns\":{\"_0\":\"Number of total released tokens\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setPoolRegistry(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"params\":{\"poolRegistry_\":\"Address of the pool registry\"}},\"sweepToken(address,address)\":{\"custom:access\":\"Only Owner\",\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"_to\":\"Recipient of the output tokens.\",\"_token\":\"The address of the BEP-20 token to sweep\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"updateAssetsState(address,address)\":{\"params\":{\"asset\":\"Asset address.\",\"comptroller\":\"Comptroller address(pool)\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"AssetsReservesUpdated(address,address,uint256)\":{\"notice\":\"Event emitted after the update of the assets reserves.\"},\"FundsReleased(address,address,uint256)\":{\"notice\":\"Emitted when funds are released\"},\"PoolRegistryUpdated(address,address)\":{\"notice\":\"Emitted when pool registry address is updated\"},\"SweepToken(address,address,uint256)\":{\"notice\":\"event emitted on sweep token success\"}},\"kind\":\"user\",\"methods\":{\"getPoolAssetReserve(address,address)\":{\"notice\":\"Get the Amount of the asset in the risk fund for the specific pool.\"},\"initialize(address,address)\":{\"notice\":\"Initializes the deployer to owner.\"},\"releaseFunds(address,address,uint256)\":{\"notice\":\"Release funds\"},\"setPoolRegistry(address)\":{\"notice\":\"Pool registry setter.\"},\"sweepToken(address,address)\":{\"notice\":\"A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\"},\"updateAssetsState(address,address)\":{\"notice\":\"Update the reserve of the asset for the specific pool after transferring to the protocol share reserve.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RiskFund/ProtocolShareReserve.sol\":\"ProtocolShareReserve\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x40031b19684ca0c912e794d08c2c0b0d8be77d3c1bdc937830a0658eff899650\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 badDebt = VToken(vToken).badDebt();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x73fdb4e4b2a2cfec75b0ef5a19491c4136a7953e1239989fb77ed26c1b7a77ac\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title PoolRegistryInterface\\n * @author Venus\\n * @notice Interface implemented by `PoolRegistry`.\\n */\\ninterface PoolRegistryInterface {\\n /**\\n * @notice Struct for a Venus interest rate pool.\\n */\\n struct VenusPool {\\n string name;\\n address creator;\\n address comptroller;\\n uint256 blockPosted;\\n uint256 timestampPosted;\\n }\\n\\n /**\\n * @notice Struct for a Venus interest rate pool metadata.\\n */\\n struct VenusPoolMetaData {\\n string category;\\n string logoURL;\\n string description;\\n }\\n\\n /// @notice Get all pools in PoolRegistry\\n function getAllPools() external view returns (VenusPool[] memory);\\n\\n /// @notice Get a pool by comptroller address\\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\\n\\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\\n\\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\\n\\n /// @notice Get the metadata of a Pool by comptroller address\\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\\n}\\n\",\"keccak256\":\"0x7e8ccd190ef019a3f8c3fcb67ed3eadd7bed32b263f88566870d138cd95ae312\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n // The block number at which to stop rewards\\n uint32 lastRewardingBlock;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n /// @notice Emitted when a reward token last rewarding block for supply is updated\\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n */\\n function setLastRewardingBlocks(\\n VToken[] calldata vTokens,\\n uint32[] calldata supplyLastRewardingBlocks,\\n uint32[] calldata borrowLastRewardingBlocks\\n ) external {\\n _checkAccessAllowed(\\\"setLastRewardingBlock(address[],uint32[],uint32[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ) {\\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for a single market.\\n * @param vToken market's whose reward token last rewarding block to be updated\\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n */\\n function _setLastRewardingBlock(\\n VToken vToken,\\n uint32 supplyLastRewardingBlock,\\n uint32 borrowLastRewardingBlock\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n uint256 blockNumber = getBlockNumber();\\n\\n require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n require(\\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n require(\\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n\\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n }\\n\\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\\n blockNumber = supplyState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\\n blockNumber = borrowState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0x0e5bede4edc4346e689de0adcf98dc9642feb55d44c1916715741c5937a34d52\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IRiskFund.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IRiskFund\\n * @author Venus\\n * @notice Interface implemented by `RiskFund`.\\n */\\ninterface IRiskFund {\\n function swapPoolsAssets(\\n address[] calldata markets,\\n uint256[] calldata amountsOutMin,\\n address[][] calldata paths,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\\n\\n function updateAssetsState(address comptroller, address asset) external;\\n\\n function convertibleBaseAsset() external view returns (address);\\n\\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xa519791948d96fb81143cdd9db0a2b753a39f1f9ca4e8c68b92997e2095f241a\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/ProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\nimport { IProtocolShareReserve } from \\\"./IProtocolShareReserve.sol\\\";\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { ReserveHelpers } from \\\"./ReserveHelpers.sol\\\";\\nimport { IRiskFund } from \\\"./IRiskFund.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\n\\ncontract ProtocolShareReserve is ExponentialNoError, ReserveHelpers, IProtocolShareReserve {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n address public protocolIncome;\\n address public riskFund;\\n // Percentage of funds not sent to the RiskFund contract when the funds are released, following the project Tokenomics\\n uint256 private constant PROTOCOL_SHARE_PERCENTAGE = 50;\\n uint256 private constant BASE_UNIT = 100;\\n\\n /// @notice Emitted when funds are released\\n event FundsReleased(address indexed comptroller, address indexed asset, uint256 amount);\\n\\n /// @notice Emitted when pool registry address is updated\\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializes the deployer to owner.\\n * @param protocolIncome_ The address protocol income will be sent to\\n * @param riskFund_ Risk fund address\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol income address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\\n */\\n function initialize(address protocolIncome_, address riskFund_) external initializer {\\n ensureNonzeroAddress(protocolIncome_);\\n ensureNonzeroAddress(riskFund_);\\n\\n __Ownable2Step_init();\\n\\n protocolIncome = protocolIncome_;\\n riskFund = riskFund_;\\n }\\n\\n /**\\n * @notice Pool registry setter.\\n * @param poolRegistry_ Address of the pool registry\\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n */\\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\\n ensureNonzeroAddress(poolRegistry_);\\n address oldPoolRegistry = poolRegistry;\\n poolRegistry = poolRegistry_;\\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\\n }\\n\\n /**\\n * @notice Release funds\\n * @param comptroller Pool's Comptroller\\n * @param asset Asset to be released\\n * @param amount Amount to release\\n * @return Number of total released tokens\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function releaseFunds(\\n address comptroller,\\n address asset,\\n uint256 amount\\n ) external nonReentrant returns (uint256) {\\n ensureNonzeroAddress(asset);\\n require(amount <= _poolsAssetsReserves[comptroller][asset], \\\"ProtocolShareReserve: Insufficient pool balance\\\");\\n\\n assetsReserves[asset] -= amount;\\n _poolsAssetsReserves[comptroller][asset] -= amount;\\n uint256 protocolIncomeAmount = mul_(\\n Exp({ mantissa: amount }),\\n div_(Exp({ mantissa: PROTOCOL_SHARE_PERCENTAGE * EXP_SCALE }), BASE_UNIT)\\n ).mantissa;\\n\\n address riskFund_ = riskFund;\\n\\n emit FundsReleased(comptroller, asset, amount);\\n\\n IERC20Upgradeable(asset).safeTransfer(protocolIncome, protocolIncomeAmount);\\n IERC20Upgradeable(asset).safeTransfer(riskFund_, amount - protocolIncomeAmount);\\n\\n // Update the pool asset's state in the risk fund for the above transfer.\\n IRiskFund(riskFund_).updateAssetsState(comptroller, asset);\\n\\n return amount;\\n }\\n\\n /**\\n * @notice Update the reserve of the asset for the specific pool after transferring to the protocol share reserve.\\n * @param comptroller Comptroller address(pool)\\n * @param asset Asset address.\\n */\\n function updateAssetsState(address comptroller, address asset)\\n public\\n override(IProtocolShareReserve, ReserveHelpers)\\n {\\n super.updateAssetsState(comptroller, asset);\\n }\\n}\\n\",\"keccak256\":\"0x871a26ce46666f37ff88034dec23d0bb9497b057a861bfd35b166a3ea3e4c785\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/ReserveHelpers.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\nimport { ComptrollerInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { PoolRegistryInterface } from \\\"../Pool/PoolRegistryInterface.sol\\\";\\n\\ncontract ReserveHelpers is Ownable2StepUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 private constant NOT_ENTERED = 1;\\n\\n uint256 private constant ENTERED = 2;\\n\\n // Store the previous state for the asset transferred to ProtocolShareReserve combined(for all pools).\\n mapping(address => uint256) public assetsReserves;\\n\\n // Store the asset's reserve per pool in the ProtocolShareReserve.\\n // Comptroller(pool) -> Asset -> amount\\n mapping(address => mapping(address => uint256)) internal _poolsAssetsReserves;\\n\\n // Address of pool registry contract\\n address public poolRegistry;\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n uint256 internal status;\\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 */\\n uint256[46] private __gap;\\n\\n /// @notice Event emitted after the update of the assets reserves.\\n /// @param comptroller Pool's Comptroller address\\n /// @param asset Token address\\n /// @param amount An amount by which the reserves have increased\\n event AssetsReservesUpdated(address indexed comptroller, address indexed asset, uint256 amount);\\n\\n /// @notice event emitted on sweep token success\\n event SweepToken(address indexed token, address indexed to, uint256 amount);\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(status != ENTERED, \\\"re-entered\\\");\\n status = ENTERED;\\n _;\\n status = NOT_ENTERED;\\n }\\n\\n /**\\n * @notice A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\\n * @param _token The address of the BEP-20 token to sweep\\n * @param _to Recipient of the output tokens.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n * @custom:access Only Owner\\n */\\n function sweepToken(address _token, address _to) external onlyOwner nonReentrant {\\n ensureNonzeroAddress(_to);\\n uint256 balanceDfference_;\\n uint256 balance_ = IERC20Upgradeable(_token).balanceOf(address(this));\\n\\n require(balance_ > assetsReserves[_token], \\\"ReserveHelpers: Zero surplus tokens\\\");\\n unchecked {\\n balanceDfference_ = balance_ - assetsReserves[_token];\\n }\\n\\n emit SweepToken(_token, _to, balanceDfference_);\\n IERC20Upgradeable(_token).safeTransfer(_to, balanceDfference_);\\n }\\n\\n /**\\n * @notice Get the Amount of the asset in the risk fund for the specific pool.\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n * @return Asset's reserve in risk fund.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function getPoolAssetReserve(address comptroller, address asset) external view returns (uint256) {\\n ensureNonzeroAddress(asset);\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"ReserveHelpers: Comptroller address invalid\\\");\\n return _poolsAssetsReserves[comptroller][asset];\\n }\\n\\n /**\\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund\\n * and transferring funds to the protocol share reserve\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function updateAssetsState(address comptroller, address asset) public virtual {\\n ensureNonzeroAddress(asset);\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"ReserveHelpers: Comptroller address invalid\\\");\\n address poolRegistry_ = poolRegistry;\\n require(poolRegistry_ != address(0), \\\"ReserveHelpers: Pool Registry address is not set\\\");\\n require(\\n PoolRegistryInterface(poolRegistry_).getVTokenForAsset(comptroller, asset) != address(0),\\n \\\"ReserveHelpers: The pool doesn't support the asset\\\"\\n );\\n\\n uint256 currentBalance = IERC20Upgradeable(asset).balanceOf(address(this));\\n uint256 assetReserve = assetsReserves[asset];\\n if (currentBalance > assetReserve) {\\n uint256 balanceDifference;\\n unchecked {\\n balanceDifference = currentBalance - assetReserve;\\n }\\n assetsReserves[asset] += balanceDifference;\\n _poolsAssetsReserves[comptroller][asset] += balanceDifference;\\n emit AssetsReservesUpdated(comptroller, asset, balanceDifference);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x689e7d9481b9a86b421de41ad87459e92146c5f2e00ac041b853ee3ad14e4bdf\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611480806100ec6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637b77cd6a11610097578063aac59a7511610066578063aac59a75146101ed578063afcff50f14610200578063e30c397814610213578063f2fde38b1461022457600080fd5b80637b77cd6a146101a35780637cf89030146101b65780638bbdf2af146101c95780638da5cb5b146101dc57600080fd5b8063485cc955116100d3578063485cc9551461016d5780636fb0527514610180578063715018a61461019357806379ba50971461019b57600080fd5b80630e3e3e3a146100fa578063258836fe1461012a578063439b55171461013f575b600080fd5b60c95461010d906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d6101383660046111c0565b610237565b005b61015f61014d3660046111f9565b60976020526000908152604090205481565b604051908152602001610121565b61013d61017b3660046111c0565b6103ea565b61015f61018e3660046111c0565b61053f565b61013d6105f3565b61013d610607565b61013d6101b13660046111f9565b610681565b60ca5461010d906001600160a01b031681565b61015f6101d7366004611216565b6106e4565b6033546001600160a01b031661010d565b61013d6101fb3660046111c0565b610968565b60995461010d906001600160a01b031681565b6065546001600160a01b031661010d565b61013d6102323660046111f9565b610976565b61023f6109e7565b6002609a54036102835760405162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b60448201526064015b60405180910390fd5b6002609a5561029181610a41565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156102da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102fe9190611257565b6001600160a01b03851660009081526097602052604090205490915081116103745760405162461bcd60e51b815260206004820152602360248201527f5265736572766548656c706572733a205a65726f20737572706c757320746f6b604482015262656e7360e81b606482015260840161027a565b6001600160a01b038481166000818152609760209081526040918290205491519185038083529550928616927f6d25be279134f4ecaa4770aff0c3d916d9e7c5ef37b65ed95dbdba411f5d54d5910160405180910390a36103df6001600160a01b0385168484610a68565b50506001609a555050565b600054610100900460ff161580801561040a5750600054600160ff909116105b806104245750303b158015610424575060005460ff166001145b6104875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161027a565b6000805460ff1916600117905580156104aa576000805461ff0019166101001790555b6104b383610a41565b6104bc82610a41565b6104c4610aba565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca805492851692909116919091179055801561053a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061054a82610a41565b826001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ab9190611270565b6105c75760405162461bcd60e51b815260040161027a90611292565b506001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b6105fb6109e7565b6106056000610ae9565b565b60655433906001600160a01b031681146106755760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161027a565b61067e81610ae9565b50565b6106896109e7565b61069281610a41565b609980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b60006002609a54036107255760405162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015260640161027a565b6002609a5561073383610a41565b6001600160a01b038085166000908152609860209081526040808320938716835292905220548211156107c05760405162461bcd60e51b815260206004820152602f60248201527f50726f746f636f6c5368617265526573657276653a20496e737566666963696560448201526e6e7420706f6f6c2062616c616e636560881b606482015260840161027a565b6001600160a01b038316600090815260976020526040812080548492906107e89084906112f3565b90915550506001600160a01b038085166000908152609860209081526040808320938716835292905290812080548492906108249084906112f3565b92505081905550600061087060405180602001604052808581525061086b6040518060200160405280670de0b6b3a76400006032610862919061130a565b90526064610b02565b610b33565b5160ca546040518581529192506001600160a01b0390811691868216918816907feed10c470424824e4a4309075162f10b9989088b23fbed2349698cedd44493fb9060200160405180910390a360c9546108d7906001600160a01b03878116911684610a68565b6108f6816108e584876112f3565b6001600160a01b0388169190610a68565b60405163aac59a7560e01b81526001600160a01b038781166004830152868116602483015282169063aac59a7590604401600060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b50506001609a5550939695505050505050565b6109728282610b72565b5050565b61097e6109e7565b606580546001600160a01b0383166001600160a01b031990911681179091556109af6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b031633146106055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161027a565b6001600160a01b03811661067e576040516342bcdf7f60e11b815260040160405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261053a908490610ea5565b600054610100900460ff16610ae15760405162461bcd60e51b815260040161027a90611329565b610605610f7a565b606580546001600160a01b031916905561067e81610faa565b6040805160208101909152600081526040518060200160405280610b2a856000015185610ffc565b90529392505050565b6040805160208101909152600081526040518060200160405280670de0b6b3a7640000610b688660000151866000015161100f565b610b2a9190611374565b610b7b81610a41565b816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdc9190611270565b610bf85760405162461bcd60e51b815260040161027a90611292565b6099546001600160a01b031680610c6a5760405162461bcd60e51b815260206004820152603060248201527f5265736572766548656c706572733a20506f6f6c20526567697374727920616460448201526f191c995cdcc81a5cc81b9bdd081cd95d60821b606482015260840161027a565b60405163266e0a7f60e01b81526001600160a01b03848116600483015283811660248301526000919083169063266e0a7f90604401602060405180830381865afa158015610cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce09190611396565b6001600160a01b031603610d515760405162461bcd60e51b815260206004820152603260248201527f5265736572766548656c706572733a2054686520706f6f6c20646f65736e2774604482015271081cdd5c1c1bdc9d081d1a1948185cdcd95d60721b606482015260840161027a565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbc9190611257565b6001600160a01b03841660009081526097602052604090205490915080821115610e9e576001600160a01b0384166000908152609760205260408120805483850392839291610e0c9084906113b3565b90915550506001600160a01b03808716600090815260986020908152604080832093891683529290529081208054839290610e489084906113b3565b92505081905550846001600160a01b0316866001600160a01b03167fc39e3e80c0219fde334a8cb5d8468b628482e23388b6e809c90cb00c63c8ce3883604051610e9491815260200190565b60405180910390a3505b5050505050565b6000610efa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661101b9092919063ffffffff16565b9050805160001480610f1b575080806020019051810190610f1b9190611270565b61053a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161027a565b600054610100900460ff16610fa15760405162461bcd60e51b815260040161027a90611329565b61060533610ae9565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006110088284611374565b9392505050565b6000611008828461130a565b606061102a8484600085611032565b949350505050565b6060824710156110935760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161027a565b600080866001600160a01b031685876040516110af91906113fb565b60006040518083038185875af1925050503d80600081146110ec576040519150601f19603f3d011682016040523d82523d6000602084013e6110f1565b606091505b50915091506111028783838761110d565b979650505050505050565b6060831561117c578251600003611175576001600160a01b0385163b6111755760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161027a565b508161102a565b61102a83838151156111915781518083602001fd5b8060405162461bcd60e51b815260040161027a9190611417565b6001600160a01b038116811461067e57600080fd5b600080604083850312156111d357600080fd5b82356111de816111ab565b915060208301356111ee816111ab565b809150509250929050565b60006020828403121561120b57600080fd5b8135611008816111ab565b60008060006060848603121561122b57600080fd5b8335611236816111ab565b92506020840135611246816111ab565b929592945050506040919091013590565b60006020828403121561126957600080fd5b5051919050565b60006020828403121561128257600080fd5b8151801515811461100857600080fd5b6020808252602b908201527f5265736572766548656c706572733a20436f6d7074726f6c6c6572206164647260408201526a195cdcc81a5b9d985b1a5960aa1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611305576113056112dd565b500390565b6000816000190483118215151615611324576113246112dd565b500290565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008261139157634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156113a857600080fd5b8151611008816111ab565b600082198211156113c6576113c66112dd565b500190565b60005b838110156113e65781810151838201526020016113ce565b838111156113f5576000848401525b50505050565b6000825161140d8184602087016113cb565b9190910192915050565b60208152600082518060208401526114368160408501602087016113cb565b601f01601f1916919091016040019291505056fea26469706673582212203e243cb1b5d00b5ce8fca153bc592828d0668926156305aabe1b7e91490ff94664736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80637b77cd6a11610097578063aac59a7511610066578063aac59a75146101ed578063afcff50f14610200578063e30c397814610213578063f2fde38b1461022457600080fd5b80637b77cd6a146101a35780637cf89030146101b65780638bbdf2af146101c95780638da5cb5b146101dc57600080fd5b8063485cc955116100d3578063485cc9551461016d5780636fb0527514610180578063715018a61461019357806379ba50971461019b57600080fd5b80630e3e3e3a146100fa578063258836fe1461012a578063439b55171461013f575b600080fd5b60c95461010d906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d6101383660046111c0565b610237565b005b61015f61014d3660046111f9565b60976020526000908152604090205481565b604051908152602001610121565b61013d61017b3660046111c0565b6103ea565b61015f61018e3660046111c0565b61053f565b61013d6105f3565b61013d610607565b61013d6101b13660046111f9565b610681565b60ca5461010d906001600160a01b031681565b61015f6101d7366004611216565b6106e4565b6033546001600160a01b031661010d565b61013d6101fb3660046111c0565b610968565b60995461010d906001600160a01b031681565b6065546001600160a01b031661010d565b61013d6102323660046111f9565b610976565b61023f6109e7565b6002609a54036102835760405162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b60448201526064015b60405180910390fd5b6002609a5561029181610a41565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156102da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102fe9190611257565b6001600160a01b03851660009081526097602052604090205490915081116103745760405162461bcd60e51b815260206004820152602360248201527f5265736572766548656c706572733a205a65726f20737572706c757320746f6b604482015262656e7360e81b606482015260840161027a565b6001600160a01b038481166000818152609760209081526040918290205491519185038083529550928616927f6d25be279134f4ecaa4770aff0c3d916d9e7c5ef37b65ed95dbdba411f5d54d5910160405180910390a36103df6001600160a01b0385168484610a68565b50506001609a555050565b600054610100900460ff161580801561040a5750600054600160ff909116105b806104245750303b158015610424575060005460ff166001145b6104875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161027a565b6000805460ff1916600117905580156104aa576000805461ff0019166101001790555b6104b383610a41565b6104bc82610a41565b6104c4610aba565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca805492851692909116919091179055801561053a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061054a82610a41565b826001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ab9190611270565b6105c75760405162461bcd60e51b815260040161027a90611292565b506001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b6105fb6109e7565b6106056000610ae9565b565b60655433906001600160a01b031681146106755760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161027a565b61067e81610ae9565b50565b6106896109e7565b61069281610a41565b609980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b60006002609a54036107255760405162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015260640161027a565b6002609a5561073383610a41565b6001600160a01b038085166000908152609860209081526040808320938716835292905220548211156107c05760405162461bcd60e51b815260206004820152602f60248201527f50726f746f636f6c5368617265526573657276653a20496e737566666963696560448201526e6e7420706f6f6c2062616c616e636560881b606482015260840161027a565b6001600160a01b038316600090815260976020526040812080548492906107e89084906112f3565b90915550506001600160a01b038085166000908152609860209081526040808320938716835292905290812080548492906108249084906112f3565b92505081905550600061087060405180602001604052808581525061086b6040518060200160405280670de0b6b3a76400006032610862919061130a565b90526064610b02565b610b33565b5160ca546040518581529192506001600160a01b0390811691868216918816907feed10c470424824e4a4309075162f10b9989088b23fbed2349698cedd44493fb9060200160405180910390a360c9546108d7906001600160a01b03878116911684610a68565b6108f6816108e584876112f3565b6001600160a01b0388169190610a68565b60405163aac59a7560e01b81526001600160a01b038781166004830152868116602483015282169063aac59a7590604401600060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b50506001609a5550939695505050505050565b6109728282610b72565b5050565b61097e6109e7565b606580546001600160a01b0383166001600160a01b031990911681179091556109af6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b031633146106055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161027a565b6001600160a01b03811661067e576040516342bcdf7f60e11b815260040160405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261053a908490610ea5565b600054610100900460ff16610ae15760405162461bcd60e51b815260040161027a90611329565b610605610f7a565b606580546001600160a01b031916905561067e81610faa565b6040805160208101909152600081526040518060200160405280610b2a856000015185610ffc565b90529392505050565b6040805160208101909152600081526040518060200160405280670de0b6b3a7640000610b688660000151866000015161100f565b610b2a9190611374565b610b7b81610a41565b816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdc9190611270565b610bf85760405162461bcd60e51b815260040161027a90611292565b6099546001600160a01b031680610c6a5760405162461bcd60e51b815260206004820152603060248201527f5265736572766548656c706572733a20506f6f6c20526567697374727920616460448201526f191c995cdcc81a5cc81b9bdd081cd95d60821b606482015260840161027a565b60405163266e0a7f60e01b81526001600160a01b03848116600483015283811660248301526000919083169063266e0a7f90604401602060405180830381865afa158015610cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce09190611396565b6001600160a01b031603610d515760405162461bcd60e51b815260206004820152603260248201527f5265736572766548656c706572733a2054686520706f6f6c20646f65736e2774604482015271081cdd5c1c1bdc9d081d1a1948185cdcd95d60721b606482015260840161027a565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbc9190611257565b6001600160a01b03841660009081526097602052604090205490915080821115610e9e576001600160a01b0384166000908152609760205260408120805483850392839291610e0c9084906113b3565b90915550506001600160a01b03808716600090815260986020908152604080832093891683529290529081208054839290610e489084906113b3565b92505081905550846001600160a01b0316866001600160a01b03167fc39e3e80c0219fde334a8cb5d8468b628482e23388b6e809c90cb00c63c8ce3883604051610e9491815260200190565b60405180910390a3505b5050505050565b6000610efa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661101b9092919063ffffffff16565b9050805160001480610f1b575080806020019051810190610f1b9190611270565b61053a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161027a565b600054610100900460ff16610fa15760405162461bcd60e51b815260040161027a90611329565b61060533610ae9565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006110088284611374565b9392505050565b6000611008828461130a565b606061102a8484600085611032565b949350505050565b6060824710156110935760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161027a565b600080866001600160a01b031685876040516110af91906113fb565b60006040518083038185875af1925050503d80600081146110ec576040519150601f19603f3d011682016040523d82523d6000602084013e6110f1565b606091505b50915091506111028783838761110d565b979650505050505050565b6060831561117c578251600003611175576001600160a01b0385163b6111755760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161027a565b508161102a565b61102a83838151156111915781518083602001fd5b8060405162461bcd60e51b815260040161027a9190611417565b6001600160a01b038116811461067e57600080fd5b600080604083850312156111d357600080fd5b82356111de816111ab565b915060208301356111ee816111ab565b809150509250929050565b60006020828403121561120b57600080fd5b8135611008816111ab565b60008060006060848603121561122b57600080fd5b8335611236816111ab565b92506020840135611246816111ab565b929592945050506040919091013590565b60006020828403121561126957600080fd5b5051919050565b60006020828403121561128257600080fd5b8151801515811461100857600080fd5b6020808252602b908201527f5265736572766548656c706572733a20436f6d7074726f6c6c6572206164647260408201526a195cdcc81a5b9d985b1a5960aa1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611305576113056112dd565b500390565b6000816000190483118215151615611324576113246112dd565b500290565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008261139157634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156113a857600080fd5b8151611008816111ab565b600082198211156113c6576113c66112dd565b500190565b60005b838110156113e65781810151838201526020016113ce565b838111156113f5576000848401525b50505050565b6000825161140d8184602087016113cb565b9190910192915050565b60208152600082518060208401526114368160408501602087016113cb565b601f01601f1916919091016040019291505056fea26469706673582212203e243cb1b5d00b5ce8fca153bc592828d0668926156305aabe1b7e91490ff94664736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "acceptOwnership()": { + "details": "The new owner accepts the ownership transfer." + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "getPoolAssetReserve(address,address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "asset": "Asset address.", + "comptroller": "Comptroller address(pool)." + }, + "returns": { + "_0": "Asset's reserve in risk fund." + } + }, + "initialize(address,address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when protocol income address is zeroZeroAddressNotAllowed is thrown when risk fund address is zero", + "params": { + "protocolIncome_": "The address protocol income will be sent to", + "riskFund_": "Risk fund address" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pendingOwner()": { + "details": "Returns the address of the pending owner." + }, + "releaseFunds(address,address,uint256)": { + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "amount": "Amount to release", + "asset": "Asset to be released", + "comptroller": "Pool's Comptroller" + }, + "returns": { + "_0": "Number of total released tokens" + } + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "setPoolRegistry(address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when pool registry address is zero", + "params": { + "poolRegistry_": "Address of the pool registry" + } + }, + "sweepToken(address,address)": { + "custom:access": "Only Owner", + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "_to": "Recipient of the output tokens.", + "_token": "The address of the BEP-20 token to sweep" + } + }, + "transferOwnership(address)": { + "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." + }, + "updateAssetsState(address,address)": { + "params": { + "asset": "Asset address.", + "comptroller": "Comptroller address(pool)" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "ZeroAddressNotAllowed()": [ + { + "notice": "Thrown if the supplied address is a zero address where it is not allowed" + } + ] + }, + "events": { + "AssetsReservesUpdated(address,address,uint256)": { + "notice": "Event emitted after the update of the assets reserves." + }, + "FundsReleased(address,address,uint256)": { + "notice": "Emitted when funds are released" + }, + "PoolRegistryUpdated(address,address)": { + "notice": "Emitted when pool registry address is updated" + }, + "SweepToken(address,address,uint256)": { + "notice": "event emitted on sweep token success" + } + }, + "kind": "user", + "methods": { + "getPoolAssetReserve(address,address)": { + "notice": "Get the Amount of the asset in the risk fund for the specific pool." + }, + "initialize(address,address)": { + "notice": "Initializes the deployer to owner." + }, + "releaseFunds(address,address,uint256)": { + "notice": "Release funds" + }, + "setPoolRegistry(address)": { + "notice": "Pool registry setter." + }, + "sweepToken(address,address)": { + "notice": "A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input" + }, + "updateAssetsState(address,address)": { + "notice": "Update the reserve of the asset for the specific pool after transferring to the protocol share reserve." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 290, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 293, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1397, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 162, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 282, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 71, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_pendingOwner", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 150, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 13338, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "assetsReserves", + "offset": 0, + "slot": "151", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 13344, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_poolsAssetsReserves", + "offset": 0, + "slot": "152", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 13346, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "poolRegistry", + "offset": 0, + "slot": "153", + "type": "t_address" + }, + { + "astId": 13349, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "status", + "offset": 0, + "slot": "154", + "type": "t_uint256" + }, + { + "astId": 13354, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "__gap", + "offset": 0, + "slot": "155", + "type": "t_array(t_uint256)46_storage" + }, + { + "astId": 13101, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "protocolIncome", + "offset": 0, + "slot": "201", + "type": "t_address" + }, + { + "astId": 13103, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "riskFund", + "offset": 0, + "slot": "202", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)46_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[46]", + "numberOfBytes": "1472" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} diff --git a/deployments/bscmainnet/ProtocolShareReserve_Proxy.json b/deployments/bscmainnet/ProtocolShareReserve_Proxy.json new file mode 100644 index 000000000..7540804c1 --- /dev/null +++ b/deployments/bscmainnet/ProtocolShareReserve_Proxy.json @@ -0,0 +1,257 @@ +{ + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "transactionIndex": 111, + "gasUsed": "817682", + "logsBloom": "0x00000000010000000000000000000000400000000000000000800000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000002000001000000000000000000000000000000010000020000000000000000000800000000800000000000000000000000400001800000080000000000000000000000000000000080000000000000800000000000000000000000000000000400000000000000000000000000000002000000000020000000000000000000040000000000000400000000000000001020000000000000000000000000000000000000000000000000000000000000000100", + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112", + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "logs": [ + { + "transactionIndex": 111, + "blockNumber": 31670925, + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000c1c56732fcafca0f66d59745ec69dc642ec20ab8" + ], + "data": "0x", + "logIndex": 258, + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112" + }, + { + "transactionIndex": 111, + "blockNumber": 31670925, + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000055a9f5374af30e3045fb491f1da3c2e8a74d168d" + ], + "data": "0x", + "logIndex": 259, + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112" + }, + { + "transactionIndex": 111, + "blockNumber": 31670925, + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 260, + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112" + }, + { + "transactionIndex": 111, + "blockNumber": 31670925, + "transactionHash": "0x47ddbdb20be15cd6c7ec5090c11a9fdf035b23ce0689b18e42141003f4ce9d9c", + "address": "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 261, + "blockHash": "0xa320e6f5001fdfe6e5a63cf1f4a8da72f57bcc0a2fab4f5903dc095ba8a9e112" + } + ], + "blockNumber": 31670925, + "cumulativeGasUsed": "13118645", + "status": 1, + "byzantium": true + }, + "args": [ + "0xc1c56732FcaFca0F66D59745Ec69DC642EC20ab8", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0x485cc955000000000000000000000000f322942f644a996a617bd29c16bd7d231d9f35e9000000000000000000000000df31a28d68a2ab381d42b380649ead7ae2a76e42" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bscmainnet/RiskFund.json b/deployments/bscmainnet/RiskFund.json new file mode 100644 index 000000000..a3413d470 --- /dev/null +++ b/deployments/bscmainnet/RiskFund.json @@ -0,0 +1,1037 @@ +{ + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ApproveFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldConvertibleBaseAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newConvertibleBaseAsset", + "type": "address" + } + ], + "name": "ConvertibleBaseAssetUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinAmountToConvert", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinAmountToConvert", + "type": "uint256" + } + ], + "name": "MinAmountToConvertUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPancakeSwapRouter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPancakeSwapRouter", + "type": "address" + } + ], + "name": "PancakeSwapRouterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldShortfallContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newShortfallContract", + "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + } + ], + "name": "SwappedPoolsAssets", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredReserveForAuction", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convertibleBaseAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "convertibleBaseAsset_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAmountToConvert", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pancakeSwapRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convertibleBaseAsset", + "type": "address" + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + } + ], + "name": "setMinAmountToConvert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + } + ], + "name": "setPancakeSwapRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "shortfallContractAddress_", + "type": "address" + } + ], + "name": "setShortfallContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "internalType": "address[][]", + "name": "paths", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapPoolsAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferReserveForAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "transactionIndex": 49, + "gasUsed": "888558", + "logsBloom": "0x00000000010000000000000000000000400000000000000000800000000000000000000000000000000000000000000000200000000000000000000000008000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000000000020000000400000000080000000000000800000000000000000000000002000000400000000000000800000000000000000000000000020000020000000000001040000400000000400000000000000001020000000000200000000000000000000000000000800000000000400000000020000", + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67", + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "logs": [ + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000087ac8dd81ec00d2183a04d22884e7fc67f6ce0c8" + ], + "data": "0x", + "logIndex": 87, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000055a9f5374af30e3045fb491f1da3c2e8a74d168d" + ], + "data": "0x", + "logIndex": 88, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", + "logIndex": 89, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 90, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 91, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 92, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + } + ], + "blockNumber": 31670886, + "cumulativeGasUsed": "5316071", + "status": 1, + "byzantium": true + }, + "args": [ + "0x87ac8dD81Ec00D2183a04D22884e7FC67f6ce0C8", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0x2a1d05470000000000000000000000008938e6da30b59c1e27d5f70a94688a89f7c815a40000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000055d398326f99059ff775485246999027b31979550000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c235550000000000000000000000000000000000000000000000000000000000000064" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0x8938E6dA30b59c1E27d5f70a94688A89F7c815a4", + "10000000000000000000", + "0x55d398326f99059fF775485246999027B3197955", + "0x4788629ABc6cFCA10F9f969efdEAa1cF70c23555", + 100 + ] + }, + "implementation": "0x87ac8dD81Ec00D2183a04D22884e7FC67f6ce0C8", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bscmainnet/RiskFund_Implementation.json b/deployments/bscmainnet/RiskFund_Implementation.json new file mode 100644 index 000000000..735e68cb8 --- /dev/null +++ b/deployments/bscmainnet/RiskFund_Implementation.json @@ -0,0 +1,1256 @@ +{ + "address": "0x87ac8dD81Ec00D2183a04D22884e7FC67f6ce0C8", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ApproveFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldConvertibleBaseAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newConvertibleBaseAsset", + "type": "address" + } + ], + "name": "ConvertibleBaseAssetUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinAmountToConvert", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinAmountToConvert", + "type": "uint256" + } + ], + "name": "MinAmountToConvertUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPancakeSwapRouter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPancakeSwapRouter", + "type": "address" + } + ], + "name": "PancakeSwapRouterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldShortfallContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newShortfallContract", + "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + } + ], + "name": "SwappedPoolsAssets", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredReserveForAuction", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convertibleBaseAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "convertibleBaseAsset_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAmountToConvert", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pancakeSwapRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convertibleBaseAsset", + "type": "address" + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + } + ], + "name": "setMinAmountToConvert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + } + ], + "name": "setPancakeSwapRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "shortfallContractAddress_", + "type": "address" + } + ], + "name": "setShortfallContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "internalType": "address[][]", + "name": "paths", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapPoolsAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferReserveForAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xf82fe32de3f970194e6fb1845418d41601b6275718eef7f5aee07d470fa44800", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0x87ac8dD81Ec00D2183a04D22884e7FC67f6ce0C8", + "transactionIndex": 85, + "gasUsed": "2577667", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000080000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xc4f776e64231aec8f09c564b9d4007e6583fe79370c927b73600dab2c81997bb", + "transactionHash": "0xf82fe32de3f970194e6fb1845418d41601b6275718eef7f5aee07d470fa44800", + "logs": [ + { + "transactionIndex": 85, + "blockNumber": 31670879, + "transactionHash": "0xf82fe32de3f970194e6fb1845418d41601b6275718eef7f5aee07d470fa44800", + "address": "0x87ac8dD81Ec00D2183a04D22884e7FC67f6ce0C8", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 110, + "blockHash": "0xc4f776e64231aec8f09c564b9d4007e6583fe79370c927b73600dab2c81997bb" + } + ], + "blockNumber": 31670879, + "cumulativeGasUsed": "7246673", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "394b060e0e484d4aa39aea929deecf07", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ApproveFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopsLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredLoops\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"calledContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"methodSignature\",\"type\":\"string\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AssetsReservesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldConvertibleBaseAsset\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newConvertibleBaseAsset\",\"type\":\"address\"}],\"name\":\"ConvertibleBaseAssetUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMaxLoopsLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newmaxLoopsLimit\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMinAmountToConvert\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMinAmountToConvert\",\"type\":\"uint256\"}],\"name\":\"MinAmountToConvertUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPancakeSwapRouter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPancakeSwapRouter\",\"type\":\"address\"}],\"name\":\"PancakeSwapRouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPoolRegistry\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPoolRegistry\",\"type\":\"address\"}],\"name\":\"PoolRegistryUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldShortfallContract\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newShortfallContract\",\"type\":\"address\"}],\"name\":\"ShortfallContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"markets\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"amountsOutMin\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalAmount\",\"type\":\"uint256\"}],\"name\":\"SwappedPoolsAssets\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"SweepToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferredReserveForAuction\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetsReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"convertibleBaseAsset\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getPoolAssetReserve\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"}],\"name\":\"getPoolsBaseAssetReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pancakeSwapRouter_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minAmountToConvert_\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"convertibleBaseAsset_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"loopsLimit_\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLoopsLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minAmountToConvert\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pancakeSwapRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_convertibleBaseAsset\",\"type\":\"address\"}],\"name\":\"setConvertibleBaseAsset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setMaxLoopsLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minAmountToConvert_\",\"type\":\"uint256\"}],\"name\":\"setMinAmountToConvert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pancakeSwapRouter_\",\"type\":\"address\"}],\"name\":\"setPancakeSwapRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"name\":\"setPoolRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"shortfallContractAddress_\",\"type\":\"address\"}],\"name\":\"setShortfallContractAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shortfall\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"markets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amountsOutMin\",\"type\":\"uint256[]\"},{\"internalType\":\"address[][]\",\"name\":\"paths\",\"type\":\"address[][]\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"name\":\"swapPoolsAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sweepToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferReserveForAuction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"updateAssetsState\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This contract does not support BNB.\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"Note that the contract is upgradeable. Use initialize() or reinitializers to set the state variables.\"},\"getPoolAssetReserve(address,address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"asset\":\"Asset address.\",\"comptroller\":\"Comptroller address(pool).\"},\"returns\":{\"_0\":\"Asset's reserve in risk fund.\"}},\"getPoolsBaseAssetReserves(address)\":{\"params\":{\"comptroller\":\"Comptroller address(pool).\"},\"returns\":{\"_0\":\"Base Asset's reserve in risk fund.\"}},\"initialize(address,uint256,address,address,uint256)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when PCS router address is zeroZeroAddressNotAllowed is thrown when convertible base asset address is zero\",\"params\":{\"accessControlManager_\":\"Address of the access control contract\",\"convertibleBaseAsset_\":\"Address of the base asset\",\"loopsLimit_\":\"Limit for the loops in the contract to avoid DOS\",\"minAmountToConvert_\":\"Minimum amount assets must be worth to convert into base asset\",\"pancakeSwapRouter_\":\"Address of the PancakeSwap router\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewAccessControlManager event\",\"details\":\"Admin function to set address of AccessControlManager\",\"params\":{\"accessControlManager_\":\"The new address of the AccessControlManager\"}},\"setConvertibleBaseAsset(address)\":{\"params\":{\"_convertibleBaseAsset\":\"Address for new convertible base asset.\"}},\"setMaxLoopsLimit(uint256)\":{\"params\":{\"limit\":\"Limit for the max loops can execute at a time\"}},\"setMinAmountToConvert(uint256)\":{\"params\":{\"minAmountToConvert_\":\"Min amount to convert.\"}},\"setPancakeSwapRouter(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when PCS router address is zero\",\"params\":{\"pancakeSwapRouter_\":\"Address of the PancakeSwap router\"}},\"setPoolRegistry(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"params\":{\"poolRegistry_\":\"Address of the pool registry\"}},\"setShortfallContractAddress(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when shortfall contract address is zero\",\"params\":{\"shortfallContractAddress_\":\"Address of the auction contract\"}},\"swapPoolsAssets(address[],uint256[],address[][],uint256)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured\",\"params\":{\"amountsOutMin\":\"Minimum amount to receive for swap\",\"deadline\":\"Deadline for the swap\",\"markets\":\"Array of vTokens whose assets to swap for base asset\",\"paths\":\"A path consisting of PCS token pairs for each swap\"},\"returns\":{\"_0\":\"Number of swapped tokens\"}},\"sweepToken(address,address)\":{\"custom:access\":\"Only Owner\",\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"_to\":\"Recipient of the output tokens.\",\"_token\":\"The address of the BEP-20 token to sweep\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"transferReserveForAuction(address,uint256)\":{\"params\":{\"amount\":\"Amount to be transferred to auction contract.\",\"comptroller\":\"Comptroller of the pool.\"},\"returns\":{\"_0\":\"Number reserved tokens.\"}},\"updateAssetsState(address,address)\":{\"params\":{\"asset\":\"Asset address.\",\"comptroller\":\"Comptroller address(pool).\"}}},\"title\":\"RiskFund\",\"version\":1},\"userdoc\":{\"errors\":{\"ApproveFailed()\":[{\"notice\":\"Thrown if a contract is unable to approve a transfer\"}],\"MaxLoopsLimitExceeded(uint256,uint256)\":[{\"notice\":\"Thrown an error on maxLoopsLimit exceeds for any loop\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"Thrown when the action is prohibited by AccessControlManager\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"AssetsReservesUpdated(address,address,uint256)\":{\"notice\":\"Event emitted after the update of the assets reserves.\"},\"ConvertibleBaseAssetUpdated(address,address)\":{\"notice\":\"Emitted when convertible base asset is updated\"},\"MaxLoopsLimitUpdated(uint256,uint256)\":{\"notice\":\"Emitted when max loops limit is set\"},\"MinAmountToConvertUpdated(uint256,uint256)\":{\"notice\":\"Emitted when minimum amount to convert is updated\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when access control manager contract address is changed\"},\"PancakeSwapRouterUpdated(address,address)\":{\"notice\":\"Emitted when PancakeSwap router contract address is updated\"},\"PoolRegistryUpdated(address,address)\":{\"notice\":\"Emitted when pool registry address is updated\"},\"ShortfallContractUpdated(address,address)\":{\"notice\":\"Emitted when shortfall contract address is updated\"},\"SwappedPoolsAssets(address[],uint256[],uint256)\":{\"notice\":\"Emitted when pools assets are swapped\"},\"SweepToken(address,address,uint256)\":{\"notice\":\"event emitted on sweep token success\"},\"TransferredReserveForAuction(address,uint256)\":{\"notice\":\"Emitted when reserves are transferred for auction\"}},\"kind\":\"user\",\"methods\":{\"accessControlManager()\":{\"notice\":\"Returns the address of the access control manager contract\"},\"getPoolAssetReserve(address,address)\":{\"notice\":\"Get the Amount of the asset in the risk fund for the specific pool.\"},\"getPoolsBaseAssetReserves(address)\":{\"notice\":\"Get the Amount of the Base asset in the risk fund for the specific pool.\"},\"initialize(address,uint256,address,address,uint256)\":{\"notice\":\"Initializes the deployer to owner.\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of AccessControlManager\"},\"setConvertibleBaseAsset(address)\":{\"notice\":\"Sets a new convertible base asset\"},\"setMaxLoopsLimit(uint256)\":{\"notice\":\"Set the limit for the loops can iterate to avoid the DOS\"},\"setMinAmountToConvert(uint256)\":{\"notice\":\"Min amount to convert setter\"},\"setPancakeSwapRouter(address)\":{\"notice\":\"PancakeSwap router address setter\"},\"setPoolRegistry(address)\":{\"notice\":\"Pool registry setter\"},\"setShortfallContractAddress(address)\":{\"notice\":\"Shortfall contract address setter\"},\"swapPoolsAssets(address[],uint256[],address[][],uint256)\":{\"notice\":\"Swap array of pool assets into base asset's tokens of at least a minimum amount\"},\"sweepToken(address,address)\":{\"notice\":\"A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\"},\"transferReserveForAuction(address,uint256)\":{\"notice\":\"Transfer tokens for auction.\"},\"updateAssetsState(address,address)\":{\"notice\":\"Update the reserve of the asset for the specific pool after transferring to risk fund.\"}},\"notice\":\"Contract with basic features to track/hold different assets for different Comptrollers.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RiskFund/RiskFund.sol\":\"RiskFund\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x40031b19684ca0c912e794d08c2c0b0d8be77d3c1bdc937830a0658eff899650\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 badDebt = VToken(vToken).badDebt();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x73fdb4e4b2a2cfec75b0ef5a19491c4136a7953e1239989fb77ed26c1b7a77ac\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/IPancakeswapV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface IPancakeswapV2Router {\\n function swapExactTokensForTokens(\\n uint256 amountIn,\\n uint256 amountOutMin,\\n address[] calldata path,\\n address to,\\n uint256 deadline\\n ) external returns (uint256[] memory amounts);\\n}\\n\",\"keccak256\":\"0x7e4d140bd2a5671389ad7a3975b65d05a4f750daf6a61c16139d123d9782b96e\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { PoolRegistryInterface } from \\\"./PoolRegistryInterface.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\n\\n/**\\n * @title PoolRegistry\\n * @author Venus\\n * @notice The Isolated Pools architecture centers around the `PoolRegistry` contract. The `PoolRegistry` maintains a directory of isolated lending\\n * pools and can perform actions like creating and registering new pools, adding new markets to existing pools, setting and updating the pool's required\\n * metadata, and providing the getter methods to get information on the pools.\\n *\\n * Isolated lending has three main components: PoolRegistry, pools, and markets. The PoolRegistry is responsible for managing pools.\\n * It can create new pools, update pool metadata and manage markets within pools. PoolRegistry contains getter methods to get the details of\\n * any existing pool like `getVTokenForAsset` and `getPoolsSupportedByAsset`. It also contains methods for updating pool metadata (`updatePoolMetadata`)\\n * and setting pool name (`setPoolName`).\\n *\\n * The directory of pools is managed through two mappings: `_poolByComptroller` which is a hashmap with the comptroller address as the key and `VenusPool` as\\n * the value and `_poolsByID` which is an array of comptroller addresses. Individual pools can be accessed by calling `getPoolByComptroller` with the pool's\\n * comptroller address. `_poolsByID` is used to iterate through all of the pools.\\n *\\n * PoolRegistry also contains a map of asset addresses called `_supportedPools` that maps to an array of assets suppored by each pool. This array of pools by\\n * asset is retrieved by calling `getPoolsSupportedByAsset`.\\n *\\n * PoolRegistry registers new isolated pools in the directory with the `createRegistryPool` method. Isolated pools are composed of independent markets with\\n * specific assets and custom risk management configurations according to their markets.\\n */\\ncontract PoolRegistry is Ownable2StepUpgradeable, AccessControlledV8, PoolRegistryInterface {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct AddMarketInput {\\n VToken vToken;\\n uint256 collateralFactor;\\n uint256 liquidationThreshold;\\n uint256 initialSupply;\\n address vTokenReceiver;\\n uint256 supplyCap;\\n uint256 borrowCap;\\n }\\n\\n uint256 internal constant MAX_POOL_NAME_LENGTH = 100;\\n\\n /**\\n * @notice Maps pool's comptroller address to metadata.\\n */\\n mapping(address => VenusPoolMetaData) public metadata;\\n\\n /**\\n * @dev Maps pool ID to pool's comptroller address\\n */\\n mapping(uint256 => address) private _poolsByID;\\n\\n /**\\n * @dev Total number of pools created.\\n */\\n uint256 private _numberOfPools;\\n\\n /**\\n * @dev Maps comptroller address to Venus pool Index.\\n */\\n mapping(address => VenusPool) private _poolByComptroller;\\n\\n /**\\n * @dev Maps pool's comptroller address to asset to vToken.\\n */\\n mapping(address => mapping(address => address)) private _vTokens;\\n\\n /**\\n * @dev Maps asset to list of supported pools.\\n */\\n mapping(address => address[]) private _supportedPools;\\n\\n /**\\n * @notice Emitted when a new Venus pool is added to the directory.\\n */\\n event PoolRegistered(address indexed comptroller, VenusPool pool);\\n\\n /**\\n * @notice Emitted when a pool name is set.\\n */\\n event PoolNameSet(address indexed comptroller, string oldName, string newName);\\n\\n /**\\n * @notice Emitted when a pool metadata is updated.\\n */\\n event PoolMetadataUpdated(\\n address indexed comptroller,\\n VenusPoolMetaData oldMetadata,\\n VenusPoolMetaData newMetadata\\n );\\n\\n /**\\n * @notice Emitted when a Market is added to the pool.\\n */\\n event MarketAdded(address indexed comptroller, address indexed vTokenAddress);\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializes the deployer to owner\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(address accessControlManager_) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n /**\\n * @notice Adds a new Venus pool to the directory\\n * @dev Price oracle must be configured before adding a pool\\n * @param name The name of the pool\\n * @param comptroller Pool's Comptroller contract\\n * @param closeFactor The pool's close factor (scaled by 1e18)\\n * @param liquidationIncentive The pool's liquidation incentive (scaled by 1e18)\\n * @param minLiquidatableCollateral Minimal collateral for regular (non-batch) liquidations flow\\n * @return index The index of the registered Venus pool\\n * @custom:error ZeroAddressNotAllowed is thrown when Comptroller address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when price oracle address is zero\\n */\\n function addPool(\\n string calldata name,\\n Comptroller comptroller,\\n uint256 closeFactor,\\n uint256 liquidationIncentive,\\n uint256 minLiquidatableCollateral\\n ) external virtual returns (uint256 index) {\\n _checkAccessAllowed(\\\"addPool(string,address,uint256,uint256,uint256)\\\");\\n // Input validation\\n ensureNonzeroAddress(address(comptroller));\\n ensureNonzeroAddress(address(comptroller.oracle()));\\n\\n uint256 poolId = _registerPool(name, address(comptroller));\\n\\n // Set Venus pool parameters\\n comptroller.setCloseFactor(closeFactor);\\n comptroller.setLiquidationIncentive(liquidationIncentive);\\n comptroller.setMinLiquidatableCollateral(minLiquidatableCollateral);\\n\\n return poolId;\\n }\\n\\n /**\\n * @notice Add a market to an existing pool and then mint to provide initial supply\\n * @param input The structure describing the parameters for adding a market to a pool\\n * @custom:error ZeroAddressNotAllowed is thrown when vToken address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when vTokenReceiver address is zero\\n */\\n function addMarket(AddMarketInput memory input) external {\\n _checkAccessAllowed(\\\"addMarket(AddMarketInput)\\\");\\n ensureNonzeroAddress(address(input.vToken));\\n ensureNonzeroAddress(input.vTokenReceiver);\\n require(input.initialSupply > 0, \\\"PoolRegistry: initialSupply is zero\\\");\\n\\n VToken vToken = input.vToken;\\n address vTokenAddress = address(vToken);\\n address comptrollerAddress = address(vToken.comptroller());\\n Comptroller comptroller = Comptroller(comptrollerAddress);\\n address underlyingAddress = vToken.underlying();\\n IERC20Upgradeable underlying = IERC20Upgradeable(underlyingAddress);\\n\\n require(_poolByComptroller[comptrollerAddress].creator != address(0), \\\"PoolRegistry: Pool not registered\\\");\\n // solhint-disable-next-line reason-string\\n require(\\n _vTokens[comptrollerAddress][underlyingAddress] == address(0),\\n \\\"PoolRegistry: Market already added for asset comptroller combination\\\"\\n );\\n\\n comptroller.supportMarket(vToken);\\n comptroller.setCollateralFactor(vToken, input.collateralFactor, input.liquidationThreshold);\\n\\n uint256[] memory newSupplyCaps = new uint256[](1);\\n uint256[] memory newBorrowCaps = new uint256[](1);\\n VToken[] memory vTokens = new VToken[](1);\\n\\n newSupplyCaps[0] = input.supplyCap;\\n newBorrowCaps[0] = input.borrowCap;\\n vTokens[0] = vToken;\\n\\n comptroller.setMarketSupplyCaps(vTokens, newSupplyCaps);\\n comptroller.setMarketBorrowCaps(vTokens, newBorrowCaps);\\n\\n _vTokens[comptrollerAddress][underlyingAddress] = vTokenAddress;\\n _supportedPools[underlyingAddress].push(comptrollerAddress);\\n\\n uint256 amountToSupply = _transferIn(underlying, msg.sender, input.initialSupply);\\n underlying.approve(vTokenAddress, 0);\\n underlying.approve(vTokenAddress, amountToSupply);\\n vToken.mintBehalf(input.vTokenReceiver, amountToSupply);\\n\\n emit MarketAdded(comptrollerAddress, vTokenAddress);\\n }\\n\\n /**\\n * @notice Modify existing Venus pool name\\n * @param comptroller Pool's Comptroller\\n * @param name New pool name\\n */\\n function setPoolName(address comptroller, string calldata name) external {\\n _checkAccessAllowed(\\\"setPoolName(address,string)\\\");\\n _ensureValidName(name);\\n VenusPool storage pool = _poolByComptroller[comptroller];\\n string memory oldName = pool.name;\\n pool.name = name;\\n emit PoolNameSet(comptroller, oldName, name);\\n }\\n\\n /**\\n * @notice Update metadata of an existing pool\\n * @param comptroller Pool's Comptroller\\n * @param metadata_ New pool metadata\\n */\\n function updatePoolMetadata(address comptroller, VenusPoolMetaData calldata metadata_) external {\\n _checkAccessAllowed(\\\"updatePoolMetadata(address,VenusPoolMetaData)\\\");\\n VenusPoolMetaData memory oldMetadata = metadata[comptroller];\\n metadata[comptroller] = metadata_;\\n emit PoolMetadataUpdated(comptroller, oldMetadata, metadata_);\\n }\\n\\n /**\\n * @notice Returns arrays of all Venus pools' data\\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\\n * @return A list of all pools within PoolRegistry, with details for each pool\\n */\\n function getAllPools() external view override returns (VenusPool[] memory) {\\n uint256 numberOfPools_ = _numberOfPools; // storage load to save gas\\n VenusPool[] memory _pools = new VenusPool[](numberOfPools_);\\n for (uint256 i = 1; i <= numberOfPools_; ++i) {\\n address comptroller = _poolsByID[i];\\n _pools[i - 1] = (_poolByComptroller[comptroller]);\\n }\\n return _pools;\\n }\\n\\n /**\\n * @param comptroller The comptroller proxy address associated to the pool\\n * @return Returns Venus pool\\n */\\n function getPoolByComptroller(address comptroller) external view override returns (VenusPool memory) {\\n return _poolByComptroller[comptroller];\\n }\\n\\n /**\\n * @param comptroller comptroller of Venus pool\\n * @return Returns Metadata of Venus pool\\n */\\n function getVenusPoolMetadata(address comptroller) external view override returns (VenusPoolMetaData memory) {\\n return metadata[comptroller];\\n }\\n\\n function getVTokenForAsset(address comptroller, address asset) external view override returns (address) {\\n return _vTokens[comptroller][asset];\\n }\\n\\n function getPoolsSupportedByAsset(address asset) external view override returns (address[] memory) {\\n return _supportedPools[asset];\\n }\\n\\n /**\\n * @dev Adds a new Venus pool to the directory (without checking msg.sender).\\n * @param name The name of the pool\\n * @param comptroller The pool's Comptroller proxy contract address\\n * @return The index of the registered Venus pool\\n */\\n function _registerPool(string calldata name, address comptroller) internal returns (uint256) {\\n VenusPool storage storedPool = _poolByComptroller[comptroller];\\n\\n require(storedPool.creator == address(0), \\\"PoolRegistry: Pool already exists in the directory.\\\");\\n _ensureValidName(name);\\n\\n ++_numberOfPools;\\n uint256 numberOfPools_ = _numberOfPools; // cache on stack to save storage read gas\\n\\n VenusPool memory pool = VenusPool(name, msg.sender, comptroller, block.number, block.timestamp);\\n\\n _poolsByID[numberOfPools_] = comptroller;\\n _poolByComptroller[comptroller] = pool;\\n\\n emit PoolRegistered(comptroller, pool);\\n return numberOfPools_;\\n }\\n\\n function _transferIn(\\n IERC20Upgradeable token,\\n address from,\\n uint256 amount\\n ) internal returns (uint256) {\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n return balanceAfter - balanceBefore;\\n }\\n\\n function _ensureValidName(string calldata name) internal pure {\\n require(bytes(name).length <= MAX_POOL_NAME_LENGTH, \\\"Pool's name is too large\\\");\\n }\\n}\\n\",\"keccak256\":\"0x6b903c298c9e2c3aaed29b4a1f76ace9fc24e50a48db22111bfc190a1a25c499\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title PoolRegistryInterface\\n * @author Venus\\n * @notice Interface implemented by `PoolRegistry`.\\n */\\ninterface PoolRegistryInterface {\\n /**\\n * @notice Struct for a Venus interest rate pool.\\n */\\n struct VenusPool {\\n string name;\\n address creator;\\n address comptroller;\\n uint256 blockPosted;\\n uint256 timestampPosted;\\n }\\n\\n /**\\n * @notice Struct for a Venus interest rate pool metadata.\\n */\\n struct VenusPoolMetaData {\\n string category;\\n string logoURL;\\n string description;\\n }\\n\\n /// @notice Get all pools in PoolRegistry\\n function getAllPools() external view returns (VenusPool[] memory);\\n\\n /// @notice Get a pool by comptroller address\\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\\n\\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\\n\\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\\n\\n /// @notice Get the metadata of a Pool by comptroller address\\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\\n}\\n\",\"keccak256\":\"0x7e8ccd190ef019a3f8c3fcb67ed3eadd7bed32b263f88566870d138cd95ae312\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n // The block number at which to stop rewards\\n uint32 lastRewardingBlock;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n /// @notice Emitted when a reward token last rewarding block for supply is updated\\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n */\\n function setLastRewardingBlocks(\\n VToken[] calldata vTokens,\\n uint32[] calldata supplyLastRewardingBlocks,\\n uint32[] calldata borrowLastRewardingBlocks\\n ) external {\\n _checkAccessAllowed(\\\"setLastRewardingBlock(address[],uint32[],uint32[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ) {\\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for a single market.\\n * @param vToken market's whose reward token last rewarding block to be updated\\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n */\\n function _setLastRewardingBlock(\\n VToken vToken,\\n uint32 supplyLastRewardingBlock,\\n uint32 borrowLastRewardingBlock\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n uint256 blockNumber = getBlockNumber();\\n\\n require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n require(\\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n require(\\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n\\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n }\\n\\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\\n blockNumber = supplyState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\\n blockNumber = borrowState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0x0e5bede4edc4346e689de0adcf98dc9642feb55d44c1916715741c5937a34d52\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IRiskFund.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IRiskFund\\n * @author Venus\\n * @notice Interface implemented by `RiskFund`.\\n */\\ninterface IRiskFund {\\n function swapPoolsAssets(\\n address[] calldata markets,\\n uint256[] calldata amountsOutMin,\\n address[][] calldata paths,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\\n\\n function updateAssetsState(address comptroller, address asset) external;\\n\\n function convertibleBaseAsset() external view returns (address);\\n\\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xa519791948d96fb81143cdd9db0a2b753a39f1f9ca4e8c68b92997e2095f241a\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/ReserveHelpers.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\nimport { ComptrollerInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { PoolRegistryInterface } from \\\"../Pool/PoolRegistryInterface.sol\\\";\\n\\ncontract ReserveHelpers is Ownable2StepUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 private constant NOT_ENTERED = 1;\\n\\n uint256 private constant ENTERED = 2;\\n\\n // Store the previous state for the asset transferred to ProtocolShareReserve combined(for all pools).\\n mapping(address => uint256) public assetsReserves;\\n\\n // Store the asset's reserve per pool in the ProtocolShareReserve.\\n // Comptroller(pool) -> Asset -> amount\\n mapping(address => mapping(address => uint256)) internal _poolsAssetsReserves;\\n\\n // Address of pool registry contract\\n address public poolRegistry;\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n uint256 internal status;\\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 */\\n uint256[46] private __gap;\\n\\n /// @notice Event emitted after the update of the assets reserves.\\n /// @param comptroller Pool's Comptroller address\\n /// @param asset Token address\\n /// @param amount An amount by which the reserves have increased\\n event AssetsReservesUpdated(address indexed comptroller, address indexed asset, uint256 amount);\\n\\n /// @notice event emitted on sweep token success\\n event SweepToken(address indexed token, address indexed to, uint256 amount);\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(status != ENTERED, \\\"re-entered\\\");\\n status = ENTERED;\\n _;\\n status = NOT_ENTERED;\\n }\\n\\n /**\\n * @notice A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\\n * @param _token The address of the BEP-20 token to sweep\\n * @param _to Recipient of the output tokens.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n * @custom:access Only Owner\\n */\\n function sweepToken(address _token, address _to) external onlyOwner nonReentrant {\\n ensureNonzeroAddress(_to);\\n uint256 balanceDfference_;\\n uint256 balance_ = IERC20Upgradeable(_token).balanceOf(address(this));\\n\\n require(balance_ > assetsReserves[_token], \\\"ReserveHelpers: Zero surplus tokens\\\");\\n unchecked {\\n balanceDfference_ = balance_ - assetsReserves[_token];\\n }\\n\\n emit SweepToken(_token, _to, balanceDfference_);\\n IERC20Upgradeable(_token).safeTransfer(_to, balanceDfference_);\\n }\\n\\n /**\\n * @notice Get the Amount of the asset in the risk fund for the specific pool.\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n * @return Asset's reserve in risk fund.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function getPoolAssetReserve(address comptroller, address asset) external view returns (uint256) {\\n ensureNonzeroAddress(asset);\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"ReserveHelpers: Comptroller address invalid\\\");\\n return _poolsAssetsReserves[comptroller][asset];\\n }\\n\\n /**\\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund\\n * and transferring funds to the protocol share reserve\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function updateAssetsState(address comptroller, address asset) public virtual {\\n ensureNonzeroAddress(asset);\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"ReserveHelpers: Comptroller address invalid\\\");\\n address poolRegistry_ = poolRegistry;\\n require(poolRegistry_ != address(0), \\\"ReserveHelpers: Pool Registry address is not set\\\");\\n require(\\n PoolRegistryInterface(poolRegistry_).getVTokenForAsset(comptroller, asset) != address(0),\\n \\\"ReserveHelpers: The pool doesn't support the asset\\\"\\n );\\n\\n uint256 currentBalance = IERC20Upgradeable(asset).balanceOf(address(this));\\n uint256 assetReserve = assetsReserves[asset];\\n if (currentBalance > assetReserve) {\\n uint256 balanceDifference;\\n unchecked {\\n balanceDifference = currentBalance - assetReserve;\\n }\\n assetsReserves[asset] += balanceDifference;\\n _poolsAssetsReserves[comptroller][asset] += balanceDifference;\\n emit AssetsReservesUpdated(comptroller, asset, balanceDifference);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x689e7d9481b9a86b421de41ad87459e92146c5f2e00ac041b853ee3ad14e4bdf\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/RiskFund.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { ComptrollerInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { IRiskFund } from \\\"./IRiskFund.sol\\\";\\nimport { ReserveHelpers } from \\\"./ReserveHelpers.sol\\\";\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { ComptrollerViewInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { PoolRegistry } from \\\"../Pool/PoolRegistry.sol\\\";\\nimport { IPancakeswapV2Router } from \\\"../IPancakeswapV2Router.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\nimport { ApproveOrRevert } from \\\"../lib/ApproveOrRevert.sol\\\";\\n\\n/**\\n * @title RiskFund\\n * @author Venus\\n * @notice Contract with basic features to track/hold different assets for different Comptrollers.\\n * @dev This contract does not support BNB.\\n */\\ncontract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, MaxLoopsLimitHelper, IRiskFund {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using ApproveOrRevert for IERC20Upgradeable;\\n\\n address public convertibleBaseAsset;\\n address public shortfall;\\n address public pancakeSwapRouter;\\n uint256 public minAmountToConvert;\\n\\n /// @notice Emitted when pool registry address is updated\\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\\n\\n /// @notice Emitted when shortfall contract address is updated\\n event ShortfallContractUpdated(address indexed oldShortfallContract, address indexed newShortfallContract);\\n\\n /// @notice Emitted when convertible base asset is updated\\n event ConvertibleBaseAssetUpdated(address indexed oldConvertibleBaseAsset, address indexed newConvertibleBaseAsset);\\n\\n /// @notice Emitted when PancakeSwap router contract address is updated\\n event PancakeSwapRouterUpdated(address indexed oldPancakeSwapRouter, address indexed newPancakeSwapRouter);\\n\\n /// @notice Emitted when minimum amount to convert is updated\\n event MinAmountToConvertUpdated(uint256 oldMinAmountToConvert, uint256 newMinAmountToConvert);\\n\\n /// @notice Emitted when pools assets are swapped\\n event SwappedPoolsAssets(address[] markets, uint256[] amountsOutMin, uint256 totalAmount);\\n\\n /// @notice Emitted when reserves are transferred for auction\\n event TransferredReserveForAuction(address indexed comptroller, uint256 amount);\\n\\n /// @dev Note that the contract is upgradeable. Use initialize() or reinitializers\\n /// to set the state variables.\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializes the deployer to owner.\\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\\n * @param minAmountToConvert_ Minimum amount assets must be worth to convert into base asset\\n * @param convertibleBaseAsset_ Address of the base asset\\n * @param accessControlManager_ Address of the access control contract\\n * @param loopsLimit_ Limit for the loops in the contract to avoid DOS\\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\\n */\\n function initialize(\\n address pancakeSwapRouter_,\\n uint256 minAmountToConvert_,\\n address convertibleBaseAsset_,\\n address accessControlManager_,\\n uint256 loopsLimit_\\n ) external initializer {\\n ensureNonzeroAddress(pancakeSwapRouter_);\\n ensureNonzeroAddress(convertibleBaseAsset_);\\n require(minAmountToConvert_ > 0, \\\"Risk Fund: Invalid min amount to convert\\\");\\n require(loopsLimit_ > 0, \\\"Risk Fund: Loops limit can not be zero\\\");\\n\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n pancakeSwapRouter = pancakeSwapRouter_;\\n minAmountToConvert = minAmountToConvert_;\\n convertibleBaseAsset = convertibleBaseAsset_;\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n /**\\n * @notice Pool registry setter\\n * @param poolRegistry_ Address of the pool registry\\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n */\\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\\n ensureNonzeroAddress(poolRegistry_);\\n address oldPoolRegistry = poolRegistry;\\n poolRegistry = poolRegistry_;\\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\\n }\\n\\n /**\\n * @notice Shortfall contract address setter\\n * @param shortfallContractAddress_ Address of the auction contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n */\\n function setShortfallContractAddress(address shortfallContractAddress_) external onlyOwner {\\n ensureNonzeroAddress(shortfallContractAddress_);\\n\\n address oldShortfallContractAddress = shortfall;\\n shortfall = shortfallContractAddress_;\\n emit ShortfallContractUpdated(oldShortfallContractAddress, shortfallContractAddress_);\\n }\\n\\n /**\\n * @notice PancakeSwap router address setter\\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\\n */\\n function setPancakeSwapRouter(address pancakeSwapRouter_) external onlyOwner {\\n ensureNonzeroAddress(pancakeSwapRouter_);\\n address oldPancakeSwapRouter = pancakeSwapRouter;\\n pancakeSwapRouter = pancakeSwapRouter_;\\n emit PancakeSwapRouterUpdated(oldPancakeSwapRouter, pancakeSwapRouter_);\\n }\\n\\n /**\\n * @notice Min amount to convert setter\\n * @param minAmountToConvert_ Min amount to convert.\\n */\\n function setMinAmountToConvert(uint256 minAmountToConvert_) external {\\n _checkAccessAllowed(\\\"setMinAmountToConvert(uint256)\\\");\\n require(minAmountToConvert_ > 0, \\\"Risk Fund: Invalid min amount to convert\\\");\\n uint256 oldMinAmountToConvert = minAmountToConvert;\\n minAmountToConvert = minAmountToConvert_;\\n emit MinAmountToConvertUpdated(oldMinAmountToConvert, minAmountToConvert_);\\n }\\n\\n /**\\n * @notice Sets a new convertible base asset\\n * @param _convertibleBaseAsset Address for new convertible base asset.\\n */\\n function setConvertibleBaseAsset(address _convertibleBaseAsset) external {\\n _checkAccessAllowed(\\\"setConvertibleBaseAsset(address)\\\");\\n require(_convertibleBaseAsset != address(0), \\\"Risk Fund: new convertible base asset address invalid\\\");\\n\\n address oldConvertibleBaseAsset = convertibleBaseAsset;\\n convertibleBaseAsset = _convertibleBaseAsset;\\n\\n emit ConvertibleBaseAssetUpdated(oldConvertibleBaseAsset, _convertibleBaseAsset);\\n }\\n\\n /**\\n * @notice Swap array of pool assets into base asset's tokens of at least a minimum amount\\n * @param markets Array of vTokens whose assets to swap for base asset\\n * @param amountsOutMin Minimum amount to receive for swap\\n * @param paths A path consisting of PCS token pairs for each swap\\n * @param deadline Deadline for the swap\\n * @return Number of swapped tokens\\n * @custom:error ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured\\n */\\n function swapPoolsAssets(\\n address[] calldata markets,\\n uint256[] calldata amountsOutMin,\\n address[][] calldata paths,\\n uint256 deadline\\n ) external override nonReentrant returns (uint256) {\\n _checkAccessAllowed(\\\"swapPoolsAssets(address[],uint256[],address[][],uint256)\\\");\\n require(deadline >= block.timestamp, \\\"Risk fund: deadline passed\\\");\\n address poolRegistry_ = poolRegistry;\\n ensureNonzeroAddress(poolRegistry_);\\n require(markets.length == amountsOutMin.length, \\\"Risk fund: markets and amountsOutMin are unequal lengths\\\");\\n require(markets.length == paths.length, \\\"Risk fund: markets and paths are unequal lengths\\\");\\n\\n uint256 totalAmount;\\n uint256 marketsCount = markets.length;\\n\\n _ensureMaxLoops(marketsCount);\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n address comptroller = address(VToken(markets[i]).comptroller());\\n\\n PoolRegistry.VenusPool memory pool = PoolRegistry(poolRegistry_).getPoolByComptroller(comptroller);\\n require(pool.comptroller == comptroller, \\\"comptroller doesn't exist pool registry\\\");\\n require(Comptroller(comptroller).isMarketListed(VToken(markets[i])), \\\"market is not listed\\\");\\n\\n uint256 swappedTokens = _swapAsset(VToken(markets[i]), comptroller, amountsOutMin[i], paths[i]);\\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] += swappedTokens;\\n assetsReserves[convertibleBaseAsset] += swappedTokens;\\n totalAmount = totalAmount + swappedTokens;\\n }\\n\\n emit SwappedPoolsAssets(markets, amountsOutMin, totalAmount);\\n\\n return totalAmount;\\n }\\n\\n /**\\n * @notice Transfer tokens for auction.\\n * @param comptroller Comptroller of the pool.\\n * @param amount Amount to be transferred to auction contract.\\n * @return Number reserved tokens.\\n */\\n function transferReserveForAuction(address comptroller, uint256 amount)\\n external\\n override\\n nonReentrant\\n returns (uint256)\\n {\\n address shortfall_ = shortfall;\\n require(msg.sender == shortfall_, \\\"Risk fund: Only callable by Shortfall contract\\\");\\n require(\\n amount <= _poolsAssetsReserves[comptroller][convertibleBaseAsset],\\n \\\"Risk Fund: Insufficient pool reserve.\\\"\\n );\\n unchecked {\\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] =\\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] -\\n amount;\\n }\\n unchecked {\\n assetsReserves[convertibleBaseAsset] = assetsReserves[convertibleBaseAsset] - amount;\\n }\\n\\n emit TransferredReserveForAuction(comptroller, amount);\\n IERC20Upgradeable(convertibleBaseAsset).safeTransfer(shortfall_, amount);\\n\\n return amount;\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Get the Amount of the Base asset in the risk fund for the specific pool.\\n * @param comptroller Comptroller address(pool).\\n * @return Base Asset's reserve in risk fund.\\n */\\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256) {\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"Risk Fund: Comptroller address invalid\\\");\\n return _poolsAssetsReserves[comptroller][convertibleBaseAsset];\\n }\\n\\n /**\\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund.\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n */\\n function updateAssetsState(address comptroller, address asset) public override(IRiskFund, ReserveHelpers) {\\n super.updateAssetsState(comptroller, asset);\\n }\\n\\n /**\\n * @dev Swap single asset to base asset.\\n * @param vToken VToken\\n * @param comptroller Comptroller address\\n * @param amountOutMin Minimum amount to receive for swap\\n * @param path A path for the swap consisting of PCS token pairs\\n * @return Number of swapped tokens.\\n */\\n function _swapAsset(\\n VToken vToken,\\n address comptroller,\\n uint256 amountOutMin,\\n address[] calldata path\\n ) internal returns (uint256) {\\n require(amountOutMin != 0, \\\"RiskFund: amountOutMin must be greater than 0 to swap vToken\\\");\\n uint256 totalAmount;\\n\\n address underlyingAsset = vToken.underlying();\\n address convertibleBaseAsset_ = convertibleBaseAsset;\\n uint256 balanceOfUnderlyingAsset = _poolsAssetsReserves[comptroller][underlyingAsset];\\n\\n if (balanceOfUnderlyingAsset == 0) {\\n return 0;\\n }\\n\\n ResilientOracleInterface oracle = ComptrollerViewInterface(comptroller).oracle();\\n oracle.updateAssetPrice(convertibleBaseAsset_);\\n Exp memory baseAssetPrice = Exp({ mantissa: oracle.getPrice(convertibleBaseAsset_) });\\n uint256 amountOutMinInUsd = mul_ScalarTruncate(baseAssetPrice, amountOutMin);\\n\\n require(amountOutMinInUsd >= minAmountToConvert, \\\"RiskFund: minAmountToConvert violated\\\");\\n\\n assetsReserves[underlyingAsset] -= balanceOfUnderlyingAsset;\\n _poolsAssetsReserves[comptroller][underlyingAsset] -= balanceOfUnderlyingAsset;\\n\\n if (underlyingAsset != convertibleBaseAsset_) {\\n require(path[0] == underlyingAsset, \\\"RiskFund: swap path must start with the underlying asset\\\");\\n require(\\n path[path.length - 1] == convertibleBaseAsset_,\\n \\\"RiskFund: finally path must be convertible base asset\\\"\\n );\\n address pancakeSwapRouter_ = pancakeSwapRouter;\\n IERC20Upgradeable(underlyingAsset).approveOrRevert(pancakeSwapRouter_, 0);\\n IERC20Upgradeable(underlyingAsset).approveOrRevert(pancakeSwapRouter_, balanceOfUnderlyingAsset);\\n uint256[] memory amounts = IPancakeswapV2Router(pancakeSwapRouter_).swapExactTokensForTokens(\\n balanceOfUnderlyingAsset,\\n amountOutMin,\\n path,\\n address(this),\\n block.timestamp\\n );\\n totalAmount = amounts[path.length - 1];\\n } else {\\n totalAmount = balanceOfUnderlyingAsset;\\n }\\n\\n return totalAmount;\\n }\\n}\\n\",\"keccak256\":\"0xb16c27419547f251890c508ee9244b6515f9fd3c35c8ba82f1b485f50dc854c4\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/ApproveOrRevert.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\nlibrary ApproveOrRevert {\\n /// @notice Thrown if a contract is unable to approve a transfer\\n error ApproveFailed();\\n\\n /// @notice Approves a transfer, ensuring that it is successful. This function supports non-compliant\\n /// tokens like the ones that don't return a boolean value on success. Thus, such approve call supports\\n /// three different kinds of tokens:\\n /// * Compliant tokens that revert on failure\\n /// * Compliant tokens that return false on failure\\n /// * Non-compliant tokens that don't return a value\\n /// @param token The contract address of the token which will be transferred\\n /// @param spender The spender contract address\\n /// @param amount The value of the transfer\\n function approveOrRevert(\\n IERC20Upgradeable token,\\n address spender,\\n uint256 amount\\n ) internal {\\n bytes memory callData = abi.encodeCall(token.approve, (spender, amount));\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory result) = address(token).call(callData);\\n\\n if (!success || (result.length != 0 && !abi.decode(result, (bool)))) {\\n revert ApproveFailed();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x60505497b334ce53f01cdaeedcee4cfc9dfd153b69e9ceecd165282c9bd2c031\",\"license\":\"MIT\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b612d2d80620000f36000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806377d4937f116100f9578063afcff50f11610097578063c8ecc0d311610071578063c8ecc0d31461037b578063e30c39781461038f578063f2fde38b146103a0578063fe3da984146103b357600080fd5b8063afcff50f1461034e578063b4a0bdf314610361578063be26317e1461037257600080fd5b806380d45a2d116100d357806380d45a2d146103045780638da5cb5b14610317578063a69bd19e14610328578063aac59a751461033b57600080fd5b806377d4937f146102d657806379ba5097146102e95780637b77cd6a146102f157600080fd5b80632e688141116101665780635f30e37b116101405780635f30e37b146102955780636fb05275146102a8578063715018a6146102bb578063746460a9146102c357600080fd5b80632e6881411461024f578063439b5517146102625780634dd9584a1461028257600080fd5b80630a9837c5146101ae5780630e32cb86146101d457806319b1faef146101e95780632455899514610215578063258836fe146102295780632a1d05471461023c575b600080fd5b6101c16101bc3660046124a8565b6103bd565b6040519081526020015b60405180910390f35b6101e76101e23660046124d4565b61058c565b005b61012e546101fd906001600160a01b031681565b6040516001600160a01b0390911681526020016101cb565b61012f546101fd906001600160a01b031681565b6101e76102373660046124f1565b6105a0565b6101e761024a36600461252a565b610731565b6101e761025d3660046124d4565b610922565b6101c16102703660046124d4565b60c96020526000908152604090205481565b6101e76102903660046124d4565b610a27565b6101c16102a33660046125d1565b610a8b565b6101c16102b63660046124f1565b610fdf565b6101e7611093565b6101e76102d1366004612674565b6110a7565b6101e76102e43660046124d4565b61114c565b6101e76111b0565b6101e76102ff3660046124d4565b611227565b6101e7610312366004612674565b61128a565b6033546001600160a01b03166101fd565b6101c16103363660046124d4565b61129b565b6101e76103493660046124f1565b611387565b60cb546101fd906001600160a01b031681565b6097546001600160a01b03166101fd565b6101c160fb5481565b61012d546101fd906001600160a01b031681565b6065546001600160a01b03166101fd565b6101e76103ae3660046124d4565b611395565b6101c16101305481565b6000600260cc54036103ea5760405162461bcd60e51b81526004016103e19061268d565b60405180910390fd5b600260cc5561012e546001600160a01b03163381146104625760405162461bcd60e51b815260206004820152602e60248201527f5269736b2066756e643a204f6e6c792063616c6c61626c652062792053686f7260448201526d1d19985b1b0818dbdb9d1c9858dd60921b60648201526084016103e1565b6001600160a01b03808516600090815260ca6020908152604080832061012d54909416835292905220548311156104e95760405162461bcd60e51b815260206004820152602560248201527f5269736b2046756e643a20496e73756666696369656e7420706f6f6c2072657360448201526432b93b329760d91b60648201526084016103e1565b6001600160a01b03808516600081815260ca6020908152604080832061012d80548716855290835281842080548a9003905554909416825260c990528290208054869003905590517fc8d0a37ed16dfaa43514df00e18f478b60d5cc7b4bfc687103948b9020f737fd906105609086815260200190565b60405180910390a261012d54610580906001600160a01b03168285611406565b5050600160cc55919050565b61059461145d565b61059d816114b7565b50565b6105a861145d565b600260cc54036105ca5760405162461bcd60e51b81526004016103e19061268d565b600260cc556105d881611575565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa158015610621573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064591906126b1565b6001600160a01b038516600090815260c9602052604090205490915081116106bb5760405162461bcd60e51b815260206004820152602360248201527f5265736572766548656c706572733a205a65726f20737572706c757320746f6b604482015262656e7360e81b60648201526084016103e1565b6001600160a01b03848116600081815260c960209081526040918290205491519185038083529550928616927f6d25be279134f4ecaa4770aff0c3d916d9e7c5ef37b65ed95dbdba411f5d54d5910160405180910390a36107266001600160a01b0385168484611406565b5050600160cc555050565b600054610100900460ff16158080156107515750600054600160ff909116105b8061076b5750303b15801561076b575060005460ff166001145b6107ce5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103e1565b6000805460ff1916600117905580156107f1576000805461ff0019166101001790555b6107fa86611575565b61080384611575565b600085116108235760405162461bcd60e51b81526004016103e1906126ca565b600082116108825760405162461bcd60e51b815260206004820152602660248201527f5269736b2046756e643a204c6f6f7073206c696d69742063616e206e6f74206260448201526565207a65726f60d01b60648201526084016103e1565b61088a61159c565b610893836115cb565b61012f80546001600160a01b038089166001600160a01b03199283161790925561013087905561012d8054928716929091169190911790556108d4826115f2565b801561091a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6109606040518060400160405280602081526020017f736574436f6e7665727469626c6542617365417373657428616464726573732981525061168c565b6001600160a01b0381166109d45760405162461bcd60e51b815260206004820152603560248201527f5269736b2046756e643a206e657720636f6e7665727469626c65206261736520604482015274185cdcd95d081859191c995cdcc81a5b9d985b1a59605a1b60648201526084016103e1565b61012d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f5fa61583da12070720613fefdd68cc6c0e464a71e009742526bd2b2e0ac62cd290600090a35050565b610a2f61145d565b610a3881611575565b61012f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fd37b9d138f53ea58d7e50292588239a46efa8f523966febf4066da96defc77fd90600090a35050565b6000600260cc5403610aaf5760405162461bcd60e51b81526004016103e19061268d565b600260cc81905550610ad8604051806060016040528060388152602001612cc06038913961168c565b42821015610b285760405162461bcd60e51b815260206004820152601a60248201527f5269736b2066756e643a20646561646c696e652070617373656400000000000060448201526064016103e1565b60cb546001600160a01b0316610b3d81611575565b878614610bb25760405162461bcd60e51b815260206004820152603860248201527f5269736b2066756e643a206d61726b65747320616e6420616d6f756e74734f7560448201527f744d696e2061726520756e657175616c206c656e67746873000000000000000060648201526084016103e1565b878414610c1a5760405162461bcd60e51b815260206004820152603060248201527f5269736b2066756e643a206d61726b65747320616e642070617468732061726560448201526f20756e657175616c206c656e6774687360801b60648201526084016103e1565b600088610c2681611726565b60005b81811015610f8c5760008c8c83818110610c4557610c45612712565b9050602002016020810190610c5a91906124d4565b6001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbb9190612728565b604051637aee632d60e01b81526001600160a01b038083166004830152919250600091871690637aee632d90602401600060405180830381865afa158015610d07573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d2f91908101906127f5565b9050816001600160a01b031681604001516001600160a01b031614610da65760405162461bcd60e51b815260206004820152602760248201527f636f6d7074726f6c6c657220646f65736e277420657869737420706f6f6c20726044820152666567697374727960c81b60648201526084016103e1565b816001600160a01b0316633d98a1e58f8f86818110610dc757610dc7612712565b9050602002016020810190610ddc91906124d4565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4491906128eb565b610e875760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d081a5cc81b9bdd081b1a5cdd195960621b60448201526064016103e1565b6000610ef68f8f86818110610e9e57610e9e612712565b9050602002016020810190610eb391906124d4565b848f8f88818110610ec657610ec6612712565b905060200201358e8e89818110610edf57610edf612712565b9050602002810190610ef1919061290d565b611757565b6001600160a01b03808516600090815260ca6020908152604080832061012d54909416835292905290812080549293508392909190610f3690849061296d565b909155505061012d546001600160a01b0316600090815260c9602052604081208054839290610f6690849061296d565b90915550610f769050818761296d565b955050505080610f8590612985565b9050610c29565b507fb17530966b045b50d4975e7f05048ca00d7335780c24f1c465165a4b94b2d37d8b8b8b8b86604051610fc49594939291906129e7565b60405180910390a150600160cc559998505050505050505050565b6000610fea82611575565b826001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104b91906128eb565b6110675760405162461bcd60e51b81526004016103e190612a42565b506001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b61109b61145d565b6110a56000611cfa565b565b6110e56040518060400160405280601e81526020017f7365744d696e416d6f756e74546f436f6e766572742875696e7432353629000081525061168c565b600081116111055760405162461bcd60e51b81526004016103e1906126ca565b61013080549082905560408051828152602081018490527fada67d0d38fa20c8ae6a5c17cb9d60b0fe7f2d4e4f27ac9ee55e54ac88de9d8d91015b60405180910390a15050565b61115461145d565b61115d81611575565b61012e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fb6e5fcf02f7fbb8acfbaa3bac4fd5abf9ff51e3f2e8884b5498927179b211b2890600090a35050565b60655433906001600160a01b0316811461121e5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016103e1565b61059d81611cfa565b61122f61145d565b61123881611575565b60cb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b61129261145d565b61059d816115f2565b6000816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fe91906128eb565b6113595760405162461bcd60e51b815260206004820152602660248201527f5269736b2046756e643a20436f6d7074726f6c6c6572206164647265737320696044820152651b9d985b1a5960d21b60648201526084016103e1565b506001600160a01b03908116600090815260ca6020908152604080832061012d549094168352929052205490565b6113918282611d13565b5050565b61139d61145d565b606580546001600160a01b0383166001600160a01b031990911681179091556113ce6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611458908490612046565b505050565b6033546001600160a01b031633146110a55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103e1565b6001600160a01b03811661151b5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b60648201526084016103e1565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa09101611140565b6001600160a01b03811661059d576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff166115c35760405162461bcd60e51b81526004016103e190612a8d565b6110a561211b565b600054610100900460ff166105945760405162461bcd60e51b81526004016103e190612a8d565b60fb54811161164e5760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b60648201526084016103e1565b60fb80549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa9101611140565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab906116bf9033908690600401612b04565b602060405180830381865afa1580156116dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170091906128eb565b90508061139157333083604051634a3fa29360e01b81526004016103e193929190612b28565b60fb5481111561059d5760fb5460405163792bfb1b60e11b81526004810191909152602481018290526044016103e1565b6000836000036117cf5760405162461bcd60e51b815260206004820152603c60248201527f5269736b46756e643a20616d6f756e744f75744d696e206d757374206265206760448201527f726561746572207468616e203020746f20737761702076546f6b656e0000000060648201526084016103e1565b600080876001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190612728565b61012d546001600160a01b03898116600090815260ca6020908152604080832084871684529091528120549394509116919081900361187a576000945050505050611cf1565b6000896001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190612728565b60405163b62cad6960e01b81526001600160a01b0385811660048301529192509082169063b62cad6990602401600060405180830381600087803b15801561192557600080fd5b505af1158015611939573d6000803e3d6000fd5b50506040805160208101918290526341976e0960e01b9091526001600160a01b03868116602483015260009350909150819084166341976e0960448301602060405180830381865afa158015611993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b791906126b1565b9052905060006119c7828c61214b565b905061013054811015611a2a5760405162461bcd60e51b815260206004820152602560248201527f5269736b46756e643a206d696e416d6f756e74546f436f6e766572742076696f6044820152641b185d195960da1b60648201526084016103e1565b6001600160a01b038616600090815260c9602052604081208054869290611a52908490612b54565b90915550506001600160a01b03808d16600090815260ca60209081526040808320938a1683529290529081208054869290611a8e908490612b54565b90915550506001600160a01b0386811690861614611ce357856001600160a01b03168a8a6000818110611ac357611ac3612712565b9050602002016020810190611ad891906124d4565b6001600160a01b031614611b545760405162461bcd60e51b815260206004820152603860248201527f5269736b46756e643a20737761702070617468206d757374207374617274207760448201527f6974682074686520756e6465726c79696e67206173736574000000000000000060648201526084016103e1565b6001600160a01b0385168a8a611b6b600182612b54565b818110611b7a57611b7a612712565b9050602002016020810190611b8f91906124d4565b6001600160a01b031614611c035760405162461bcd60e51b815260206004820152603560248201527f5269736b46756e643a2066696e616c6c792070617468206d75737420626520636044820152741bdb9d995c9d1a589b194818985cd948185cdcd95d605a1b60648201526084016103e1565b61012f546001600160a01b0390811690611c2190881682600061216b565b611c356001600160a01b038816828761216b565b6000816001600160a01b03166338ed1739878f8f8f30426040518763ffffffff1660e01b8152600401611c6d96959493929190612b6b565b6000604051808303816000875af1158015611c8c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cb49190810190612ba9565b905080611cc260018d612b54565b81518110611cd257611cd2612712565b602002602001015198505050611ce7565b8396505b5094955050505050505b95945050505050565b606580546001600160a01b031916905561059d81612257565b611d1c81611575565b816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7d91906128eb565b611d995760405162461bcd60e51b81526004016103e190612a42565b60cb546001600160a01b031680611e0b5760405162461bcd60e51b815260206004820152603060248201527f5265736572766548656c706572733a20506f6f6c20526567697374727920616460448201526f191c995cdcc81a5cc81b9bdd081cd95d60821b60648201526084016103e1565b60405163266e0a7f60e01b81526001600160a01b03848116600483015283811660248301526000919083169063266e0a7f90604401602060405180830381865afa158015611e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e819190612728565b6001600160a01b031603611ef25760405162461bcd60e51b815260206004820152603260248201527f5265736572766548656c706572733a2054686520706f6f6c20646f65736e2774604482015271081cdd5c1c1bdc9d081d1a1948185cdcd95d60721b60648201526084016103e1565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5d91906126b1565b6001600160a01b038416600090815260c960205260409020549091508082111561203f576001600160a01b038416600090815260c960205260408120805483850392839291611fad90849061296d565b90915550506001600160a01b03808716600090815260ca6020908152604080832093891683529290529081208054839290611fe990849061296d565b92505081905550846001600160a01b0316866001600160a01b03167fc39e3e80c0219fde334a8cb5d8468b628482e23388b6e809c90cb00c63c8ce388360405161203591815260200190565b60405180910390a3505b5050505050565b600061209b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122a99092919063ffffffff16565b90508051600014806120bc5750808060200190518101906120bc91906128eb565b6114585760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103e1565b600054610100900460ff166121425760405162461bcd60e51b81526004016103e190612a8d565b6110a533611cfa565b60008061215884846122b8565b9050612163816122e9565b949350505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1790529151909160009182918716906121c9908590612c4f565b6000604051808303816000865af19150503d8060008114612206576040519150601f19603f3d011682016040523d82523d6000602084013e61220b565b606091505b5091509150811580612239575080511580159061223957508080602001905181019061223791906128eb565b155b1561091a57604051633e3f8f7360e01b815260040160405180910390fd5b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606121638484600085612307565b60408051602081019091526000815260405180602001604052806122e08560000151856123e2565b90529392505050565b805160009061230190670de0b6b3a764000090612c6b565b92915050565b6060824710156123685760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103e1565b600080866001600160a01b031685876040516123849190612c4f565b60006040518083038185875af1925050503d80600081146123c1576040519150601f19603f3d011682016040523d82523d6000602084013e6123c6565b606091505b50915091506123d7878383876123f5565b979650505050505050565b60006123ee8284612c8d565b9392505050565b6060831561246457825160000361245d576001600160a01b0385163b61245d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103e1565b5081612163565b61216383838151156124795781518083602001fd5b8060405162461bcd60e51b81526004016103e19190612cac565b6001600160a01b038116811461059d57600080fd5b600080604083850312156124bb57600080fd5b82356124c681612493565b946020939093013593505050565b6000602082840312156124e657600080fd5b81356123ee81612493565b6000806040838503121561250457600080fd5b823561250f81612493565b9150602083013561251f81612493565b809150509250929050565b600080600080600060a0868803121561254257600080fd5b853561254d81612493565b945060208601359350604086013561256481612493565b9250606086013561257481612493565b949793965091946080013592915050565b60008083601f84011261259757600080fd5b50813567ffffffffffffffff8111156125af57600080fd5b6020830191508360208260051b85010111156125ca57600080fd5b9250929050565b60008060008060008060006080888a0312156125ec57600080fd5b873567ffffffffffffffff8082111561260457600080fd5b6126108b838c01612585565b909950975060208a013591508082111561262957600080fd5b6126358b838c01612585565b909750955060408a013591508082111561264e57600080fd5b5061265b8a828b01612585565b989b979a50959894979596606090950135949350505050565b60006020828403121561268657600080fd5b5035919050565b6020808252600a90820152691c994b595b9d195c995960b21b604082015260600190565b6000602082840312156126c357600080fd5b5051919050565b60208082526028908201527f5269736b2046756e643a20496e76616c6964206d696e20616d6f756e7420746f6040820152670818dbdb9d995c9d60c21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561273a57600080fd5b81516123ee81612493565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561277e5761277e612745565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156127ad576127ad612745565b604052919050565b60005b838110156127d05781810151838201526020016127b8565b838111156127df576000848401525b50505050565b80516127f081612493565b919050565b6000602080838503121561280857600080fd5b825167ffffffffffffffff8082111561282057600080fd5b9084019060a0828703121561283457600080fd5b61283c61275b565b82518281111561284b57600080fd5b8301601f8101881361285c57600080fd5b80518381111561286e5761286e612745565b612880601f8201601f19168701612784565b9350808452888682840101111561289657600080fd5b6128a5818786018885016127b5565b50508181526128b58484016127e5565b848201526128c5604084016127e5565b604082015260608301516060820152608083015160808201528094505050505092915050565b6000602082840312156128fd57600080fd5b815180151581146123ee57600080fd5b6000808335601e1984360301811261292457600080fd5b83018035915067ffffffffffffffff82111561293f57600080fd5b6020019150600581901b36038213156125ca57600080fd5b634e487b7160e01b600052601160045260246000fd5b6000821982111561298057612980612957565b500190565b60006001820161299757612997612957565b5060010190565b8183526000602080850194508260005b858110156129dc5781356129c181612493565b6001600160a01b0316875295820195908201906001016129ae565b509495945050505050565b6060815260006129fb60608301878961299e565b82810360208401528481526001600160fb1b03851115612a1a57600080fd5b8460051b80876020840137600091016020019081526040929092019290925295945050505050565b6020808252602b908201527f5265736572766548656c706572733a20436f6d7074726f6c6c6572206164647260408201526a195cdcc81a5b9d985b1a5960aa1b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008151808452612af08160208601602086016127b5565b601f01601f19169290920160200192915050565b6001600160a01b038316815260406020820181905260009061216390830184612ad8565b6001600160a01b03848116825283166020820152606060408201819052600090611cf190830184612ad8565b600082821015612b6657612b66612957565b500390565b86815285602082015260a060408201526000612b8b60a08301868861299e565b6001600160a01b039490941660608301525060800152949350505050565b60006020808385031215612bbc57600080fd5b825167ffffffffffffffff80821115612bd457600080fd5b818501915085601f830112612be857600080fd5b815181811115612bfa57612bfa612745565b8060051b9150612c0b848301612784565b8181529183018401918481019088841115612c2557600080fd5b938501935b83851015612c4357845182529385019390850190612c2a565b98975050505050505050565b60008251612c618184602087016127b5565b9190910192915050565b600082612c8857634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612ca757612ca7612957565b500290565b6020815260006123ee6020830184612ad856fe73776170506f6f6c7341737365747328616464726573735b5d2c75696e743235365b5d2c616464726573735b5d5b5d2c75696e7432353629a26469706673582212200df4784c551e6f296a40813ffbdb6c465608d0b9582f5f659a9257b405a4147e64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806377d4937f116100f9578063afcff50f11610097578063c8ecc0d311610071578063c8ecc0d31461037b578063e30c39781461038f578063f2fde38b146103a0578063fe3da984146103b357600080fd5b8063afcff50f1461034e578063b4a0bdf314610361578063be26317e1461037257600080fd5b806380d45a2d116100d357806380d45a2d146103045780638da5cb5b14610317578063a69bd19e14610328578063aac59a751461033b57600080fd5b806377d4937f146102d657806379ba5097146102e95780637b77cd6a146102f157600080fd5b80632e688141116101665780635f30e37b116101405780635f30e37b146102955780636fb05275146102a8578063715018a6146102bb578063746460a9146102c357600080fd5b80632e6881411461024f578063439b5517146102625780634dd9584a1461028257600080fd5b80630a9837c5146101ae5780630e32cb86146101d457806319b1faef146101e95780632455899514610215578063258836fe146102295780632a1d05471461023c575b600080fd5b6101c16101bc3660046124a8565b6103bd565b6040519081526020015b60405180910390f35b6101e76101e23660046124d4565b61058c565b005b61012e546101fd906001600160a01b031681565b6040516001600160a01b0390911681526020016101cb565b61012f546101fd906001600160a01b031681565b6101e76102373660046124f1565b6105a0565b6101e761024a36600461252a565b610731565b6101e761025d3660046124d4565b610922565b6101c16102703660046124d4565b60c96020526000908152604090205481565b6101e76102903660046124d4565b610a27565b6101c16102a33660046125d1565b610a8b565b6101c16102b63660046124f1565b610fdf565b6101e7611093565b6101e76102d1366004612674565b6110a7565b6101e76102e43660046124d4565b61114c565b6101e76111b0565b6101e76102ff3660046124d4565b611227565b6101e7610312366004612674565b61128a565b6033546001600160a01b03166101fd565b6101c16103363660046124d4565b61129b565b6101e76103493660046124f1565b611387565b60cb546101fd906001600160a01b031681565b6097546001600160a01b03166101fd565b6101c160fb5481565b61012d546101fd906001600160a01b031681565b6065546001600160a01b03166101fd565b6101e76103ae3660046124d4565b611395565b6101c16101305481565b6000600260cc54036103ea5760405162461bcd60e51b81526004016103e19061268d565b60405180910390fd5b600260cc5561012e546001600160a01b03163381146104625760405162461bcd60e51b815260206004820152602e60248201527f5269736b2066756e643a204f6e6c792063616c6c61626c652062792053686f7260448201526d1d19985b1b0818dbdb9d1c9858dd60921b60648201526084016103e1565b6001600160a01b03808516600090815260ca6020908152604080832061012d54909416835292905220548311156104e95760405162461bcd60e51b815260206004820152602560248201527f5269736b2046756e643a20496e73756666696369656e7420706f6f6c2072657360448201526432b93b329760d91b60648201526084016103e1565b6001600160a01b03808516600081815260ca6020908152604080832061012d80548716855290835281842080548a9003905554909416825260c990528290208054869003905590517fc8d0a37ed16dfaa43514df00e18f478b60d5cc7b4bfc687103948b9020f737fd906105609086815260200190565b60405180910390a261012d54610580906001600160a01b03168285611406565b5050600160cc55919050565b61059461145d565b61059d816114b7565b50565b6105a861145d565b600260cc54036105ca5760405162461bcd60e51b81526004016103e19061268d565b600260cc556105d881611575565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa158015610621573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064591906126b1565b6001600160a01b038516600090815260c9602052604090205490915081116106bb5760405162461bcd60e51b815260206004820152602360248201527f5265736572766548656c706572733a205a65726f20737572706c757320746f6b604482015262656e7360e81b60648201526084016103e1565b6001600160a01b03848116600081815260c960209081526040918290205491519185038083529550928616927f6d25be279134f4ecaa4770aff0c3d916d9e7c5ef37b65ed95dbdba411f5d54d5910160405180910390a36107266001600160a01b0385168484611406565b5050600160cc555050565b600054610100900460ff16158080156107515750600054600160ff909116105b8061076b5750303b15801561076b575060005460ff166001145b6107ce5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103e1565b6000805460ff1916600117905580156107f1576000805461ff0019166101001790555b6107fa86611575565b61080384611575565b600085116108235760405162461bcd60e51b81526004016103e1906126ca565b600082116108825760405162461bcd60e51b815260206004820152602660248201527f5269736b2046756e643a204c6f6f7073206c696d69742063616e206e6f74206260448201526565207a65726f60d01b60648201526084016103e1565b61088a61159c565b610893836115cb565b61012f80546001600160a01b038089166001600160a01b03199283161790925561013087905561012d8054928716929091169190911790556108d4826115f2565b801561091a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6109606040518060400160405280602081526020017f736574436f6e7665727469626c6542617365417373657428616464726573732981525061168c565b6001600160a01b0381166109d45760405162461bcd60e51b815260206004820152603560248201527f5269736b2046756e643a206e657720636f6e7665727469626c65206261736520604482015274185cdcd95d081859191c995cdcc81a5b9d985b1a59605a1b60648201526084016103e1565b61012d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f5fa61583da12070720613fefdd68cc6c0e464a71e009742526bd2b2e0ac62cd290600090a35050565b610a2f61145d565b610a3881611575565b61012f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fd37b9d138f53ea58d7e50292588239a46efa8f523966febf4066da96defc77fd90600090a35050565b6000600260cc5403610aaf5760405162461bcd60e51b81526004016103e19061268d565b600260cc81905550610ad8604051806060016040528060388152602001612cc06038913961168c565b42821015610b285760405162461bcd60e51b815260206004820152601a60248201527f5269736b2066756e643a20646561646c696e652070617373656400000000000060448201526064016103e1565b60cb546001600160a01b0316610b3d81611575565b878614610bb25760405162461bcd60e51b815260206004820152603860248201527f5269736b2066756e643a206d61726b65747320616e6420616d6f756e74734f7560448201527f744d696e2061726520756e657175616c206c656e67746873000000000000000060648201526084016103e1565b878414610c1a5760405162461bcd60e51b815260206004820152603060248201527f5269736b2066756e643a206d61726b65747320616e642070617468732061726560448201526f20756e657175616c206c656e6774687360801b60648201526084016103e1565b600088610c2681611726565b60005b81811015610f8c5760008c8c83818110610c4557610c45612712565b9050602002016020810190610c5a91906124d4565b6001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbb9190612728565b604051637aee632d60e01b81526001600160a01b038083166004830152919250600091871690637aee632d90602401600060405180830381865afa158015610d07573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d2f91908101906127f5565b9050816001600160a01b031681604001516001600160a01b031614610da65760405162461bcd60e51b815260206004820152602760248201527f636f6d7074726f6c6c657220646f65736e277420657869737420706f6f6c20726044820152666567697374727960c81b60648201526084016103e1565b816001600160a01b0316633d98a1e58f8f86818110610dc757610dc7612712565b9050602002016020810190610ddc91906124d4565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4491906128eb565b610e875760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d081a5cc81b9bdd081b1a5cdd195960621b60448201526064016103e1565b6000610ef68f8f86818110610e9e57610e9e612712565b9050602002016020810190610eb391906124d4565b848f8f88818110610ec657610ec6612712565b905060200201358e8e89818110610edf57610edf612712565b9050602002810190610ef1919061290d565b611757565b6001600160a01b03808516600090815260ca6020908152604080832061012d54909416835292905290812080549293508392909190610f3690849061296d565b909155505061012d546001600160a01b0316600090815260c9602052604081208054839290610f6690849061296d565b90915550610f769050818761296d565b955050505080610f8590612985565b9050610c29565b507fb17530966b045b50d4975e7f05048ca00d7335780c24f1c465165a4b94b2d37d8b8b8b8b86604051610fc49594939291906129e7565b60405180910390a150600160cc559998505050505050505050565b6000610fea82611575565b826001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104b91906128eb565b6110675760405162461bcd60e51b81526004016103e190612a42565b506001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b61109b61145d565b6110a56000611cfa565b565b6110e56040518060400160405280601e81526020017f7365744d696e416d6f756e74546f436f6e766572742875696e7432353629000081525061168c565b600081116111055760405162461bcd60e51b81526004016103e1906126ca565b61013080549082905560408051828152602081018490527fada67d0d38fa20c8ae6a5c17cb9d60b0fe7f2d4e4f27ac9ee55e54ac88de9d8d91015b60405180910390a15050565b61115461145d565b61115d81611575565b61012e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fb6e5fcf02f7fbb8acfbaa3bac4fd5abf9ff51e3f2e8884b5498927179b211b2890600090a35050565b60655433906001600160a01b0316811461121e5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016103e1565b61059d81611cfa565b61122f61145d565b61123881611575565b60cb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b61129261145d565b61059d816115f2565b6000816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fe91906128eb565b6113595760405162461bcd60e51b815260206004820152602660248201527f5269736b2046756e643a20436f6d7074726f6c6c6572206164647265737320696044820152651b9d985b1a5960d21b60648201526084016103e1565b506001600160a01b03908116600090815260ca6020908152604080832061012d549094168352929052205490565b6113918282611d13565b5050565b61139d61145d565b606580546001600160a01b0383166001600160a01b031990911681179091556113ce6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611458908490612046565b505050565b6033546001600160a01b031633146110a55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103e1565b6001600160a01b03811661151b5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b60648201526084016103e1565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa09101611140565b6001600160a01b03811661059d576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff166115c35760405162461bcd60e51b81526004016103e190612a8d565b6110a561211b565b600054610100900460ff166105945760405162461bcd60e51b81526004016103e190612a8d565b60fb54811161164e5760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b60648201526084016103e1565b60fb80549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa9101611140565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab906116bf9033908690600401612b04565b602060405180830381865afa1580156116dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170091906128eb565b90508061139157333083604051634a3fa29360e01b81526004016103e193929190612b28565b60fb5481111561059d5760fb5460405163792bfb1b60e11b81526004810191909152602481018290526044016103e1565b6000836000036117cf5760405162461bcd60e51b815260206004820152603c60248201527f5269736b46756e643a20616d6f756e744f75744d696e206d757374206265206760448201527f726561746572207468616e203020746f20737761702076546f6b656e0000000060648201526084016103e1565b600080876001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190612728565b61012d546001600160a01b03898116600090815260ca6020908152604080832084871684529091528120549394509116919081900361187a576000945050505050611cf1565b6000896001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190612728565b60405163b62cad6960e01b81526001600160a01b0385811660048301529192509082169063b62cad6990602401600060405180830381600087803b15801561192557600080fd5b505af1158015611939573d6000803e3d6000fd5b50506040805160208101918290526341976e0960e01b9091526001600160a01b03868116602483015260009350909150819084166341976e0960448301602060405180830381865afa158015611993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b791906126b1565b9052905060006119c7828c61214b565b905061013054811015611a2a5760405162461bcd60e51b815260206004820152602560248201527f5269736b46756e643a206d696e416d6f756e74546f436f6e766572742076696f6044820152641b185d195960da1b60648201526084016103e1565b6001600160a01b038616600090815260c9602052604081208054869290611a52908490612b54565b90915550506001600160a01b03808d16600090815260ca60209081526040808320938a1683529290529081208054869290611a8e908490612b54565b90915550506001600160a01b0386811690861614611ce357856001600160a01b03168a8a6000818110611ac357611ac3612712565b9050602002016020810190611ad891906124d4565b6001600160a01b031614611b545760405162461bcd60e51b815260206004820152603860248201527f5269736b46756e643a20737761702070617468206d757374207374617274207760448201527f6974682074686520756e6465726c79696e67206173736574000000000000000060648201526084016103e1565b6001600160a01b0385168a8a611b6b600182612b54565b818110611b7a57611b7a612712565b9050602002016020810190611b8f91906124d4565b6001600160a01b031614611c035760405162461bcd60e51b815260206004820152603560248201527f5269736b46756e643a2066696e616c6c792070617468206d75737420626520636044820152741bdb9d995c9d1a589b194818985cd948185cdcd95d605a1b60648201526084016103e1565b61012f546001600160a01b0390811690611c2190881682600061216b565b611c356001600160a01b038816828761216b565b6000816001600160a01b03166338ed1739878f8f8f30426040518763ffffffff1660e01b8152600401611c6d96959493929190612b6b565b6000604051808303816000875af1158015611c8c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cb49190810190612ba9565b905080611cc260018d612b54565b81518110611cd257611cd2612712565b602002602001015198505050611ce7565b8396505b5094955050505050505b95945050505050565b606580546001600160a01b031916905561059d81612257565b611d1c81611575565b816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7d91906128eb565b611d995760405162461bcd60e51b81526004016103e190612a42565b60cb546001600160a01b031680611e0b5760405162461bcd60e51b815260206004820152603060248201527f5265736572766548656c706572733a20506f6f6c20526567697374727920616460448201526f191c995cdcc81a5cc81b9bdd081cd95d60821b60648201526084016103e1565b60405163266e0a7f60e01b81526001600160a01b03848116600483015283811660248301526000919083169063266e0a7f90604401602060405180830381865afa158015611e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e819190612728565b6001600160a01b031603611ef25760405162461bcd60e51b815260206004820152603260248201527f5265736572766548656c706572733a2054686520706f6f6c20646f65736e2774604482015271081cdd5c1c1bdc9d081d1a1948185cdcd95d60721b60648201526084016103e1565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5d91906126b1565b6001600160a01b038416600090815260c960205260409020549091508082111561203f576001600160a01b038416600090815260c960205260408120805483850392839291611fad90849061296d565b90915550506001600160a01b03808716600090815260ca6020908152604080832093891683529290529081208054839290611fe990849061296d565b92505081905550846001600160a01b0316866001600160a01b03167fc39e3e80c0219fde334a8cb5d8468b628482e23388b6e809c90cb00c63c8ce388360405161203591815260200190565b60405180910390a3505b5050505050565b600061209b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122a99092919063ffffffff16565b90508051600014806120bc5750808060200190518101906120bc91906128eb565b6114585760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103e1565b600054610100900460ff166121425760405162461bcd60e51b81526004016103e190612a8d565b6110a533611cfa565b60008061215884846122b8565b9050612163816122e9565b949350505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1790529151909160009182918716906121c9908590612c4f565b6000604051808303816000865af19150503d8060008114612206576040519150601f19603f3d011682016040523d82523d6000602084013e61220b565b606091505b5091509150811580612239575080511580159061223957508080602001905181019061223791906128eb565b155b1561091a57604051633e3f8f7360e01b815260040160405180910390fd5b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606121638484600085612307565b60408051602081019091526000815260405180602001604052806122e08560000151856123e2565b90529392505050565b805160009061230190670de0b6b3a764000090612c6b565b92915050565b6060824710156123685760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103e1565b600080866001600160a01b031685876040516123849190612c4f565b60006040518083038185875af1925050503d80600081146123c1576040519150601f19603f3d011682016040523d82523d6000602084013e6123c6565b606091505b50915091506123d7878383876123f5565b979650505050505050565b60006123ee8284612c8d565b9392505050565b6060831561246457825160000361245d576001600160a01b0385163b61245d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103e1565b5081612163565b61216383838151156124795781518083602001fd5b8060405162461bcd60e51b81526004016103e19190612cac565b6001600160a01b038116811461059d57600080fd5b600080604083850312156124bb57600080fd5b82356124c681612493565b946020939093013593505050565b6000602082840312156124e657600080fd5b81356123ee81612493565b6000806040838503121561250457600080fd5b823561250f81612493565b9150602083013561251f81612493565b809150509250929050565b600080600080600060a0868803121561254257600080fd5b853561254d81612493565b945060208601359350604086013561256481612493565b9250606086013561257481612493565b949793965091946080013592915050565b60008083601f84011261259757600080fd5b50813567ffffffffffffffff8111156125af57600080fd5b6020830191508360208260051b85010111156125ca57600080fd5b9250929050565b60008060008060008060006080888a0312156125ec57600080fd5b873567ffffffffffffffff8082111561260457600080fd5b6126108b838c01612585565b909950975060208a013591508082111561262957600080fd5b6126358b838c01612585565b909750955060408a013591508082111561264e57600080fd5b5061265b8a828b01612585565b989b979a50959894979596606090950135949350505050565b60006020828403121561268657600080fd5b5035919050565b6020808252600a90820152691c994b595b9d195c995960b21b604082015260600190565b6000602082840312156126c357600080fd5b5051919050565b60208082526028908201527f5269736b2046756e643a20496e76616c6964206d696e20616d6f756e7420746f6040820152670818dbdb9d995c9d60c21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561273a57600080fd5b81516123ee81612493565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561277e5761277e612745565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156127ad576127ad612745565b604052919050565b60005b838110156127d05781810151838201526020016127b8565b838111156127df576000848401525b50505050565b80516127f081612493565b919050565b6000602080838503121561280857600080fd5b825167ffffffffffffffff8082111561282057600080fd5b9084019060a0828703121561283457600080fd5b61283c61275b565b82518281111561284b57600080fd5b8301601f8101881361285c57600080fd5b80518381111561286e5761286e612745565b612880601f8201601f19168701612784565b9350808452888682840101111561289657600080fd5b6128a5818786018885016127b5565b50508181526128b58484016127e5565b848201526128c5604084016127e5565b604082015260608301516060820152608083015160808201528094505050505092915050565b6000602082840312156128fd57600080fd5b815180151581146123ee57600080fd5b6000808335601e1984360301811261292457600080fd5b83018035915067ffffffffffffffff82111561293f57600080fd5b6020019150600581901b36038213156125ca57600080fd5b634e487b7160e01b600052601160045260246000fd5b6000821982111561298057612980612957565b500190565b60006001820161299757612997612957565b5060010190565b8183526000602080850194508260005b858110156129dc5781356129c181612493565b6001600160a01b0316875295820195908201906001016129ae565b509495945050505050565b6060815260006129fb60608301878961299e565b82810360208401528481526001600160fb1b03851115612a1a57600080fd5b8460051b80876020840137600091016020019081526040929092019290925295945050505050565b6020808252602b908201527f5265736572766548656c706572733a20436f6d7074726f6c6c6572206164647260408201526a195cdcc81a5b9d985b1a5960aa1b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008151808452612af08160208601602086016127b5565b601f01601f19169290920160200192915050565b6001600160a01b038316815260406020820181905260009061216390830184612ad8565b6001600160a01b03848116825283166020820152606060408201819052600090611cf190830184612ad8565b600082821015612b6657612b66612957565b500390565b86815285602082015260a060408201526000612b8b60a08301868861299e565b6001600160a01b039490941660608301525060800152949350505050565b60006020808385031215612bbc57600080fd5b825167ffffffffffffffff80821115612bd457600080fd5b818501915085601f830112612be857600080fd5b815181811115612bfa57612bfa612745565b8060051b9150612c0b848301612784565b8181529183018401918481019088841115612c2557600080fd5b938501935b83851015612c4357845182529385019390850190612c2a565b98975050505050505050565b60008251612c618184602087016127b5565b9190910192915050565b600082612c8857634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612ca757612ca7612957565b500290565b6020815260006123ee6020830184612ad856fe73776170506f6f6c7341737365747328616464726573735b5d2c75696e743235365b5d2c616464726573735b5d5b5d2c75696e7432353629a26469706673582212200df4784c551e6f296a40813ffbdb6c465608d0b9582f5f659a9257b405a4147e64736f6c634300080d0033", + "devdoc": { + "author": "Venus", + "details": "This contract does not support BNB.", + "kind": "dev", + "methods": { + "acceptOwnership()": { + "details": "The new owner accepts the ownership transfer." + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor", + "details": "Note that the contract is upgradeable. Use initialize() or reinitializers to set the state variables." + }, + "getPoolAssetReserve(address,address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "asset": "Asset address.", + "comptroller": "Comptroller address(pool)." + }, + "returns": { + "_0": "Asset's reserve in risk fund." + } + }, + "getPoolsBaseAssetReserves(address)": { + "params": { + "comptroller": "Comptroller address(pool)." + }, + "returns": { + "_0": "Base Asset's reserve in risk fund." + } + }, + "initialize(address,uint256,address,address,uint256)": { + "custom:error": "ZeroAddressNotAllowed is thrown when PCS router address is zeroZeroAddressNotAllowed is thrown when convertible base asset address is zero", + "params": { + "accessControlManager_": "Address of the access control contract", + "convertibleBaseAsset_": "Address of the base asset", + "loopsLimit_": "Limit for the loops in the contract to avoid DOS", + "minAmountToConvert_": "Minimum amount assets must be worth to convert into base asset", + "pancakeSwapRouter_": "Address of the PancakeSwap router" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pendingOwner()": { + "details": "Returns the address of the pending owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "setAccessControlManager(address)": { + "custom:access": "Only Governance", + "custom:event": "Emits NewAccessControlManager event", + "details": "Admin function to set address of AccessControlManager", + "params": { + "accessControlManager_": "The new address of the AccessControlManager" + } + }, + "setConvertibleBaseAsset(address)": { + "params": { + "_convertibleBaseAsset": "Address for new convertible base asset." + } + }, + "setMaxLoopsLimit(uint256)": { + "params": { + "limit": "Limit for the max loops can execute at a time" + } + }, + "setMinAmountToConvert(uint256)": { + "params": { + "minAmountToConvert_": "Min amount to convert." + } + }, + "setPancakeSwapRouter(address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when PCS router address is zero", + "params": { + "pancakeSwapRouter_": "Address of the PancakeSwap router" + } + }, + "setPoolRegistry(address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when pool registry address is zero", + "params": { + "poolRegistry_": "Address of the pool registry" + } + }, + "setShortfallContractAddress(address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when shortfall contract address is zero", + "params": { + "shortfallContractAddress_": "Address of the auction contract" + } + }, + "swapPoolsAssets(address[],uint256[],address[][],uint256)": { + "custom:error": "ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured", + "params": { + "amountsOutMin": "Minimum amount to receive for swap", + "deadline": "Deadline for the swap", + "markets": "Array of vTokens whose assets to swap for base asset", + "paths": "A path consisting of PCS token pairs for each swap" + }, + "returns": { + "_0": "Number of swapped tokens" + } + }, + "sweepToken(address,address)": { + "custom:access": "Only Owner", + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "_to": "Recipient of the output tokens.", + "_token": "The address of the BEP-20 token to sweep" + } + }, + "transferOwnership(address)": { + "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." + }, + "transferReserveForAuction(address,uint256)": { + "params": { + "amount": "Amount to be transferred to auction contract.", + "comptroller": "Comptroller of the pool." + }, + "returns": { + "_0": "Number reserved tokens." + } + }, + "updateAssetsState(address,address)": { + "params": { + "asset": "Asset address.", + "comptroller": "Comptroller address(pool)." + } + } + }, + "title": "RiskFund", + "version": 1 + }, + "userdoc": { + "errors": { + "ApproveFailed()": [ + { + "notice": "Thrown if a contract is unable to approve a transfer" + } + ], + "MaxLoopsLimitExceeded(uint256,uint256)": [ + { + "notice": "Thrown an error on maxLoopsLimit exceeds for any loop" + } + ], + "Unauthorized(address,address,string)": [ + { + "notice": "Thrown when the action is prohibited by AccessControlManager" + } + ], + "ZeroAddressNotAllowed()": [ + { + "notice": "Thrown if the supplied address is a zero address where it is not allowed" + } + ] + }, + "events": { + "AssetsReservesUpdated(address,address,uint256)": { + "notice": "Event emitted after the update of the assets reserves." + }, + "ConvertibleBaseAssetUpdated(address,address)": { + "notice": "Emitted when convertible base asset is updated" + }, + "MaxLoopsLimitUpdated(uint256,uint256)": { + "notice": "Emitted when max loops limit is set" + }, + "MinAmountToConvertUpdated(uint256,uint256)": { + "notice": "Emitted when minimum amount to convert is updated" + }, + "NewAccessControlManager(address,address)": { + "notice": "Emitted when access control manager contract address is changed" + }, + "PancakeSwapRouterUpdated(address,address)": { + "notice": "Emitted when PancakeSwap router contract address is updated" + }, + "PoolRegistryUpdated(address,address)": { + "notice": "Emitted when pool registry address is updated" + }, + "ShortfallContractUpdated(address,address)": { + "notice": "Emitted when shortfall contract address is updated" + }, + "SwappedPoolsAssets(address[],uint256[],uint256)": { + "notice": "Emitted when pools assets are swapped" + }, + "SweepToken(address,address,uint256)": { + "notice": "event emitted on sweep token success" + }, + "TransferredReserveForAuction(address,uint256)": { + "notice": "Emitted when reserves are transferred for auction" + } + }, + "kind": "user", + "methods": { + "accessControlManager()": { + "notice": "Returns the address of the access control manager contract" + }, + "getPoolAssetReserve(address,address)": { + "notice": "Get the Amount of the asset in the risk fund for the specific pool." + }, + "getPoolsBaseAssetReserves(address)": { + "notice": "Get the Amount of the Base asset in the risk fund for the specific pool." + }, + "initialize(address,uint256,address,address,uint256)": { + "notice": "Initializes the deployer to owner." + }, + "setAccessControlManager(address)": { + "notice": "Sets the address of AccessControlManager" + }, + "setConvertibleBaseAsset(address)": { + "notice": "Sets a new convertible base asset" + }, + "setMaxLoopsLimit(uint256)": { + "notice": "Set the limit for the loops can iterate to avoid the DOS" + }, + "setMinAmountToConvert(uint256)": { + "notice": "Min amount to convert setter" + }, + "setPancakeSwapRouter(address)": { + "notice": "PancakeSwap router address setter" + }, + "setPoolRegistry(address)": { + "notice": "Pool registry setter" + }, + "setShortfallContractAddress(address)": { + "notice": "Shortfall contract address setter" + }, + "swapPoolsAssets(address[],uint256[],address[][],uint256)": { + "notice": "Swap array of pool assets into base asset's tokens of at least a minimum amount" + }, + "sweepToken(address,address)": { + "notice": "A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input" + }, + "transferReserveForAuction(address,uint256)": { + "notice": "Transfer tokens for auction." + }, + "updateAssetsState(address,address)": { + "notice": "Update the reserve of the asset for the specific pool after transferring to risk fund." + } + }, + "notice": "Contract with basic features to track/hold different assets for different Comptrollers.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 290, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 293, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1397, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 162, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 282, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 71, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_pendingOwner", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 150, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 3341, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_accessControlManager", + "offset": 0, + "slot": "151", + "type": "t_contract(IAccessControlManagerV8)3525" + }, + { + "astId": 3346, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 13338, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "assetsReserves", + "offset": 0, + "slot": "201", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 13344, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_poolsAssetsReserves", + "offset": 0, + "slot": "202", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 13346, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "poolRegistry", + "offset": 0, + "slot": "203", + "type": "t_address" + }, + { + "astId": 13349, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "status", + "offset": 0, + "slot": "204", + "type": "t_uint256" + }, + { + "astId": 13354, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "205", + "type": "t_array(t_uint256)46_storage" + }, + { + "astId": 10571, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "maxLoopsLimit", + "offset": 0, + "slot": "251", + "type": "t_uint256" + }, + { + "astId": 10576, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 13647, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "convertibleBaseAsset", + "offset": 0, + "slot": "301", + "type": "t_address" + }, + { + "astId": 13649, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "shortfall", + "offset": 0, + "slot": "302", + "type": "t_address" + }, + { + "astId": 13651, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "pancakeSwapRouter", + "offset": 0, + "slot": "303", + "type": "t_address" + }, + { + "astId": 13653, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "minAmountToConvert", + "offset": 0, + "slot": "304", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)46_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[46]", + "numberOfBytes": "1472" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IAccessControlManagerV8)3525": { + "encoding": "inplace", + "label": "contract IAccessControlManagerV8", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} diff --git a/deployments/bscmainnet/RiskFund_Proxy.json b/deployments/bscmainnet/RiskFund_Proxy.json new file mode 100644 index 000000000..af7e00d39 --- /dev/null +++ b/deployments/bscmainnet/RiskFund_Proxy.json @@ -0,0 +1,277 @@ +{ + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "transactionIndex": 49, + "gasUsed": "888558", + "logsBloom": "0x00000000010000000000000000000000400000000000000000800000000000000000000000000000000000000000000000200000000000000000000000008000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000000000020000000400000000080000000000000800000000000000000000000002000000400000000000000800000000000000000000000000020000020000000000001040000400000000400000000000000001020000000000200000000000000000000000000000800000000000400000000020000", + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67", + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "logs": [ + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000087ac8dd81ec00d2183a04d22884e7fc67f6ce0c8" + ], + "data": "0x", + "logIndex": 87, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000055a9f5374af30e3045fb491f1da3c2e8a74d168d" + ], + "data": "0x", + "logIndex": 88, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", + "logIndex": 89, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 90, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 91, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + }, + { + "transactionIndex": 49, + "blockNumber": 31670886, + "transactionHash": "0xae915a962973c42c5c57c1996d903612f73792b1d2593b6732ede95c9aa96bc3", + "address": "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 92, + "blockHash": "0x257df431491cd4263b736de0d3b3eb095a88e52ef7be61d7b6f0195be0c46d67" + } + ], + "blockNumber": 31670886, + "cumulativeGasUsed": "5316071", + "status": 1, + "byzantium": true + }, + "args": [ + "0x87ac8dD81Ec00D2183a04D22884e7FC67f6ce0C8", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0x2a1d05470000000000000000000000008938e6da30b59c1e27d5f70a94688a89f7c815a40000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000055d398326f99059ff775485246999027b31979550000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c235550000000000000000000000000000000000000000000000000000000000000064" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bscmainnet/Shortfall.json b/deployments/bscmainnet/Shortfall.json new file mode 100644 index 000000000..8a88e9796 --- /dev/null +++ b/deployments/bscmainnet/Shortfall.json @@ -0,0 +1,1192 @@ +{ + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableBalance", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "owedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientDebt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFind", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketDebt", + "type": "uint256[]" + } + ], + "name": "AuctionClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "AuctionRestarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketsDebt", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "name": "AuctionStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "bidder", + "type": "address" + } + ], + "name": "BidPlaced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldIncentiveBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newIncentiveBps", + "type": "uint256" + } + ], + "name": "IncentiveBpsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinimumPoolBadDebt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "MinimumPoolBadDebtUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldNextBidderBlockLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newNextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "NextBidderBlockLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldWaitForFirstBidder", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWaitForFirstBidder", + "type": "uint256" + } + ], + "name": "WaitForFirstBidderUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "auctions", + "outputs": [ + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "internalType": "enum Shortfall.AuctionStatus", + "name": "status", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "highestBidBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "claimTokenDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "closeAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "incentiveBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IRiskFund", + "name": "riskFund_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minimumPoolBadDebt_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minimumPoolBadDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextBidderBlockLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "placeBid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "restartAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resumeAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "contract IRiskFund", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "startAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalTokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_incentiveBps", + "type": "uint256" + } + ], + "name": "updateIncentiveBps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "updateMinimumPoolBadDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "updateNextBidderBlockLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "updatePoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_waitForFirstBidder", + "type": "uint256" + } + ], + "name": "updateWaitForFirstBidder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "waitForFirstBidder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "transactionIndex": 44, + "gasUsed": "933014", + "logsBloom": "0x00000000010000000000000000000000400000000000000000800000000000000000000000000000000000000000000000200000000000000000000000009000000000000000000400000000000002000001000000000000000000000000000000000000030000000000000000000800000000800000002000000000000000400000000000000000000000000000000000000000000080000000000000800000000000000000000000000000000400000000040000800000000000000000000000000020000000000000000000040000000000000400000000000000001020000000000000000000000000000000004000000800000000000000000000000000", + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b", + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000916e607af3250ecb2fd4ea82a37eb2756a20e1fc" + ], + "data": "0x", + "logIndex": 95, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + }, + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000055a9f5374af30e3045fb491f1da3c2e8a74d168d" + ], + "data": "0x", + "logIndex": 96, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + }, + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", + "logIndex": 97, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + }, + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 98, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + }, + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 99, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + } + ], + "blockNumber": 31670900, + "cumulativeGasUsed": "4614383", + "status": 1, + "byzantium": true + }, + "args": [ + "0x916e607AF3250ECB2Fd4ea82A37Eb2756A20e1fC", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0xc350a1b5000000000000000000000000df31a28d68a2ab381d42b380649ead7ae2a76e4200000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42", + "1000000000000000000000", + "0x4788629ABc6cFCA10F9f969efdEAa1cF70c23555" + ] + }, + "implementation": "0x916e607AF3250ECB2Fd4ea82A37Eb2756A20e1fC", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bscmainnet/Shortfall_Implementation.json b/deployments/bscmainnet/Shortfall_Implementation.json new file mode 100644 index 000000000..abc0b4dde --- /dev/null +++ b/deployments/bscmainnet/Shortfall_Implementation.json @@ -0,0 +1,1641 @@ +{ + "address": "0x916e607AF3250ECB2Fd4ea82A37Eb2756A20e1fC", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableBalance", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "owedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientDebt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFind", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketDebt", + "type": "uint256[]" + } + ], + "name": "AuctionClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "AuctionRestarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketsDebt", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "name": "AuctionStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "bidder", + "type": "address" + } + ], + "name": "BidPlaced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldIncentiveBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newIncentiveBps", + "type": "uint256" + } + ], + "name": "IncentiveBpsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinimumPoolBadDebt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "MinimumPoolBadDebtUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldNextBidderBlockLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newNextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "NextBidderBlockLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldWaitForFirstBidder", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWaitForFirstBidder", + "type": "uint256" + } + ], + "name": "WaitForFirstBidderUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "auctions", + "outputs": [ + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "internalType": "enum Shortfall.AuctionStatus", + "name": "status", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "highestBidBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "claimTokenDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "closeAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "incentiveBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IRiskFund", + "name": "riskFund_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minimumPoolBadDebt_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minimumPoolBadDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextBidderBlockLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "placeBid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "restartAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resumeAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "contract IRiskFund", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "startAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalTokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_incentiveBps", + "type": "uint256" + } + ], + "name": "updateIncentiveBps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "updateMinimumPoolBadDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "updateNextBidderBlockLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "updatePoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_waitForFirstBidder", + "type": "uint256" + } + ], + "name": "updateWaitForFirstBidder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "waitForFirstBidder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xb52e9cab1643fcc3836a7b4531380d4432acd32eae648c9fe3906ed07c10c624", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0x916e607AF3250ECB2Fd4ea82A37Eb2756A20e1fC", + "transactionIndex": 58, + "gasUsed": "3151308", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000800000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000", + "blockHash": "0x604abfff2629e612a620cc2494ae603994c7956f5515b3a49bc615de666617ab", + "transactionHash": "0xb52e9cab1643fcc3836a7b4531380d4432acd32eae648c9fe3906ed07c10c624", + "logs": [ + { + "transactionIndex": 58, + "blockNumber": 31670894, + "transactionHash": "0xb52e9cab1643fcc3836a7b4531380d4432acd32eae648c9fe3906ed07c10c624", + "address": "0x916e607AF3250ECB2Fd4ea82A37Eb2756A20e1fC", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 99, + "blockHash": "0x604abfff2629e612a620cc2494ae603994c7956f5515b3a49bc615de666617ab" + } + ], + "blockNumber": 31670894, + "cumulativeGasUsed": "6741266", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "394b060e0e484d4aa39aea929deecf07", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableBalance\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"owedAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"InsufficientDebt\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"calledContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"methodSignature\",\"type\":\"string\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"highestBidder\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"highestBidBps\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"seizedRiskFind\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"contract VToken[]\",\"name\":\"markets\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"marketDebt\",\"type\":\"uint256[]\"}],\"name\":\"AuctionClosed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"}],\"name\":\"AuctionRestarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"enum Shortfall.AuctionType\",\"name\":\"auctionType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"contract VToken[]\",\"name\":\"markets\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"marketsDebt\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"seizedRiskFund\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startBidBps\",\"type\":\"uint256\"}],\"name\":\"AuctionStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AuctionsPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AuctionsResumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"bidBps\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bidder\",\"type\":\"address\"}],\"name\":\"BidPlaced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldIncentiveBps\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newIncentiveBps\",\"type\":\"uint256\"}],\"name\":\"IncentiveBpsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMinimumPoolBadDebt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMinimumPoolBadDebt\",\"type\":\"uint256\"}],\"name\":\"MinimumPoolBadDebtUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNextBidderBlockLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNextBidderBlockLimit\",\"type\":\"uint256\"}],\"name\":\"NextBidderBlockLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPoolRegistry\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPoolRegistry\",\"type\":\"address\"}],\"name\":\"PoolRegistryUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenDebtAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenDebtClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldWaitForFirstBidder\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newWaitForFirstBidder\",\"type\":\"uint256\"}],\"name\":\"WaitForFirstBidderUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"auctions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"startBlock\",\"type\":\"uint256\"},{\"internalType\":\"enum Shortfall.AuctionType\",\"name\":\"auctionType\",\"type\":\"uint8\"},{\"internalType\":\"enum Shortfall.AuctionStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"seizedRiskFund\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"highestBidder\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"highestBidBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"highestBidBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startBidBps\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"auctionsPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"claimTokenDebt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"}],\"name\":\"closeAuction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"incentiveBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IRiskFund\",\"name\":\"riskFund_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minimumPoolBadDebt_\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minimumPoolBadDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextBidderBlockLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pauseAuctions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"bidBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"}],\"name\":\"placeBid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"}],\"name\":\"restartAuction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resumeAuctions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"riskFund\",\"outputs\":[{\"internalType\":\"contract IRiskFund\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"}],\"name\":\"startAuction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"tokenDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalTokenDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_incentiveBps\",\"type\":\"uint256\"}],\"name\":\"updateIncentiveBps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minimumPoolBadDebt\",\"type\":\"uint256\"}],\"name\":\"updateMinimumPoolBadDebt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nextBidderBlockLimit\",\"type\":\"uint256\"}],\"name\":\"updateNextBidderBlockLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"name\":\"updatePoolRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_waitForFirstBidder\",\"type\":\"uint256\"}],\"name\":\"updateWaitForFirstBidder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"waitForFirstBidder\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"errors\":{\"InsufficientBalance(address,address,uint256,uint256)\":[{\"params\":{\"amount\":\"The amount of tokens the contract is trying to transfer\",\"availableBalance\":\"The amount of tokens the contract currently has\",\"recipient\":\"The recipient of the transfer\",\"token\":\"The token the contract is trying to transfer\"}}],\"InsufficientDebt(address,address,uint256,uint256)\":[{\"params\":{\"amount\":\"The amount of tokens the user is trying to claim\",\"owedAmount\":\"The amount of tokens the contract owes to the user\",\"token\":\"The token the user is trying to claim\"}}]},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"claimTokenDebt(address,uint256)\":{\"custom:error\":\"InsufficientDebt The contract doesn't have enough debt to the user\",\"params\":{\"amount_\":\"The amount of tokens to claim (or max uint256 to claim all)\",\"token\":\"The token to claim\"}},\"closeAuction(address)\":{\"custom:event\":\"Emits AuctionClosed event on successful close\",\"params\":{\"comptroller\":\"Comptroller address of the pool\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"initialize(address,uint256,address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when convertible base asset address is zeroZeroAddressNotAllowed is thrown when risk fund address is zero\",\"params\":{\"accessControlManager_\":\"AccessControlManager contract address\",\"minimumPoolBadDebt_\":\"Minimum bad debt in base asset for a pool to start auction\",\"riskFund_\":\"RiskFund contract address\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pauseAuctions()\":{\"custom:access\":\"Restricted by ACM\",\"custom:error\":\"Errors is auctions are paused\",\"custom:event\":\"Emits AuctionsPaused on success\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"placeBid(address,uint256,uint256)\":{\"custom:event\":\"Emits BidPlaced event on success\",\"params\":{\"auctionStartBlock\":\"The block number when auction started\",\"bidBps\":\"The bid percent of the risk fund or bad debt depending on auction type\",\"comptroller\":\"Comptroller address of the pool\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"restartAuction(address)\":{\"custom:event\":\"Emits AuctionRestarted event on successful restart\",\"params\":{\"comptroller\":\"Address of the pool\"}},\"resumeAuctions()\":{\"custom:access\":\"Restricted by ACM\",\"custom:error\":\"Errors is auctions are active\",\"custom:event\":\"Emits AuctionsResumed on success\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewAccessControlManager event\",\"details\":\"Admin function to set address of AccessControlManager\",\"params\":{\"accessControlManager_\":\"The new address of the AccessControlManager\"}},\"startAuction(address)\":{\"custom:event\":\"Emits AuctionStarted event on successErrors if auctions are paused\",\"params\":{\"comptroller\":\"Comptroller address of the pool\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"updateIncentiveBps(uint256)\":{\"custom:access\":\"Restricted by ACM\",\"custom:event\":\"Emits IncentiveBpsUpdated on success\",\"params\":{\"_incentiveBps\":\"New incentive BPS\"}},\"updateMinimumPoolBadDebt(uint256)\":{\"custom:access\":\"Restricted by ACM\",\"custom:event\":\"Emits MinimumPoolBadDebtUpdated on success\",\"params\":{\"_minimumPoolBadDebt\":\"Minimum bad debt in BUSD for a pool to start auction\"}},\"updateNextBidderBlockLimit(uint256)\":{\"custom:access\":\"Restricted by ACM\",\"custom:event\":\"Emits NextBidderBlockLimitUpdated on success\",\"params\":{\"_nextBidderBlockLimit\":\"New next bidder block limit\"}},\"updatePoolRegistry(address)\":{\"custom:access\":\"Restricted to owner\",\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"custom:event\":\"Emits PoolRegistryUpdated on success\",\"details\":\"After Pool Registry is deployed we need to set the pool registry address\",\"params\":{\"poolRegistry_\":\"Address of pool registry contract\"}},\"updateWaitForFirstBidder(uint256)\":{\"custom:access\":\"Restricted by ACM\",\"custom:event\":\"Emits WaitForFirstBidderUpdated on success\",\"params\":{\"_waitForFirstBidder\":\"New wait for first bidder block count\"}}},\"stateVariables\":{\"MAX_BPS\":{\"details\":\"Max basis points i.e., 100%\"}},\"title\":\"Shortfall\",\"version\":1},\"userdoc\":{\"errors\":{\"InsufficientBalance(address,address,uint256,uint256)\":[{\"notice\":\"Thrown if trying to transfer more tokens than the contract currently has\"}],\"InsufficientDebt(address,address,uint256,uint256)\":[{\"notice\":\"Thrown if the user tries to claim more tokens than they are owed\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"Thrown when the action is prohibited by AccessControlManager\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"AuctionClosed(address,uint256,address,uint256,uint256,address[],uint256[])\":{\"notice\":\"Emitted when a auction is completed\"},\"AuctionRestarted(address,uint256)\":{\"notice\":\"Emitted when a auction is restarted\"},\"AuctionStarted(address,uint256,uint8,address[],uint256[],uint256,uint256)\":{\"notice\":\"Emitted when a auction starts\"},\"AuctionsPaused(address)\":{\"notice\":\"Emitted when auctions are paused\"},\"AuctionsResumed(address)\":{\"notice\":\"Emitted when auctions are unpaused\"},\"BidPlaced(address,uint256,uint256,address)\":{\"notice\":\"Emitted when a bid is placed\"},\"IncentiveBpsUpdated(uint256,uint256)\":{\"notice\":\"Emitted when incentiveBps is updated\"},\"MinimumPoolBadDebtUpdated(uint256,uint256)\":{\"notice\":\"Emitted when minimum pool bad debt is updated\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when access control manager contract address is changed\"},\"NextBidderBlockLimitUpdated(uint256,uint256)\":{\"notice\":\"Emitted when next bidder block limit is updated\"},\"PoolRegistryUpdated(address,address)\":{\"notice\":\"Emitted when pool registry address is updated\"},\"TokenDebtAdded(address,address,uint256)\":{\"notice\":\"Emitted when the contract's debt to the user is increased due to a failed transfer\"},\"TokenDebtClaimed(address,address,uint256)\":{\"notice\":\"Emitted when a user claims tokens that the contract owes them\"},\"WaitForFirstBidderUpdated(uint256,uint256)\":{\"notice\":\"Emitted when wait for first bidder block count is updated\"}},\"kind\":\"user\",\"methods\":{\"accessControlManager()\":{\"notice\":\"Returns the address of the access control manager contract\"},\"auctions(address)\":{\"notice\":\"Auctions for each pool\"},\"auctionsPaused()\":{\"notice\":\"Boolean of if auctions are paused\"},\"claimTokenDebt(address,uint256)\":{\"notice\":\"Transfers the tokens we owe to msg.sender, if any\"},\"closeAuction(address)\":{\"notice\":\"Close an auction\"},\"incentiveBps()\":{\"notice\":\"Incentive to auction participants, initial value set to 1000 or 10%\"},\"initialize(address,uint256,address)\":{\"notice\":\"Initialize the shortfall contract\"},\"minimumPoolBadDebt()\":{\"notice\":\"Minimum USD debt in pool for shortfall to trigger\"},\"nextBidderBlockLimit()\":{\"notice\":\"Time to wait for next bidder. Initially waits for 100 blocks\"},\"pauseAuctions()\":{\"notice\":\"Pause auctions. This disables starting new auctions but lets the current auction finishes\"},\"placeBid(address,uint256,uint256)\":{\"notice\":\"Place a bid greater than the previous in an ongoing auction\"},\"poolRegistry()\":{\"notice\":\"Pool registry address\"},\"restartAuction(address)\":{\"notice\":\"Restart an auction\"},\"resumeAuctions()\":{\"notice\":\"Resume paused auctions.\"},\"riskFund()\":{\"notice\":\"Risk fund address\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of AccessControlManager\"},\"startAuction(address)\":{\"notice\":\"Start a auction when there is not currently one active\"},\"tokenDebt(address,address)\":{\"notice\":\"Mapping (IERC20Upgradeable token => (address user => uint256 amount)). Tracks failed transfers: when a token transfer fails, we record the amount of the transfer, so that the user can redeem this debt later.\"},\"totalTokenDebt(address)\":{\"notice\":\"Mapping (IERC20Upgradeable token => uint256 amount) shows how many tokens the contract owes to all users. This is useful for accounting to understand how much of balanceOf(address(this)) is already owed to users.\"},\"updateIncentiveBps(uint256)\":{\"notice\":\"Updates the incentive BPS\"},\"updateMinimumPoolBadDebt(uint256)\":{\"notice\":\"Update minimum pool bad debt to start auction\"},\"updateNextBidderBlockLimit(uint256)\":{\"notice\":\"Update next bidder block limit which is used determine when an auction can be closed\"},\"updatePoolRegistry(address)\":{\"notice\":\"Update the pool registry this shortfall supports\"},\"updateWaitForFirstBidder(uint256)\":{\"notice\":\"Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted\"},\"waitForFirstBidder()\":{\"notice\":\"Time to wait for first bidder. Initially waits for 100 blocks\"}},\"notice\":\"Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset` is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value. This value is set and can be changed by the authorized accounts. If the pool\\u2019s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise, if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the risk fund in exchange for paying off all the pool's bad debt.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Shortfall/Shortfall.sol\":\"Shortfall\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\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\",\"keccak256\":\"0xb82ef33f43b6b96109687d91b39c94573fdccaaa423fe28e8ba0977b31c023e0\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x40031b19684ca0c912e794d08c2c0b0d8be77d3c1bdc937830a0658eff899650\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 badDebt = VToken(vToken).badDebt();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x73fdb4e4b2a2cfec75b0ef5a19491c4136a7953e1239989fb77ed26c1b7a77ac\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { PoolRegistryInterface } from \\\"./PoolRegistryInterface.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\n\\n/**\\n * @title PoolRegistry\\n * @author Venus\\n * @notice The Isolated Pools architecture centers around the `PoolRegistry` contract. The `PoolRegistry` maintains a directory of isolated lending\\n * pools and can perform actions like creating and registering new pools, adding new markets to existing pools, setting and updating the pool's required\\n * metadata, and providing the getter methods to get information on the pools.\\n *\\n * Isolated lending has three main components: PoolRegistry, pools, and markets. The PoolRegistry is responsible for managing pools.\\n * It can create new pools, update pool metadata and manage markets within pools. PoolRegistry contains getter methods to get the details of\\n * any existing pool like `getVTokenForAsset` and `getPoolsSupportedByAsset`. It also contains methods for updating pool metadata (`updatePoolMetadata`)\\n * and setting pool name (`setPoolName`).\\n *\\n * The directory of pools is managed through two mappings: `_poolByComptroller` which is a hashmap with the comptroller address as the key and `VenusPool` as\\n * the value and `_poolsByID` which is an array of comptroller addresses. Individual pools can be accessed by calling `getPoolByComptroller` with the pool's\\n * comptroller address. `_poolsByID` is used to iterate through all of the pools.\\n *\\n * PoolRegistry also contains a map of asset addresses called `_supportedPools` that maps to an array of assets suppored by each pool. This array of pools by\\n * asset is retrieved by calling `getPoolsSupportedByAsset`.\\n *\\n * PoolRegistry registers new isolated pools in the directory with the `createRegistryPool` method. Isolated pools are composed of independent markets with\\n * specific assets and custom risk management configurations according to their markets.\\n */\\ncontract PoolRegistry is Ownable2StepUpgradeable, AccessControlledV8, PoolRegistryInterface {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct AddMarketInput {\\n VToken vToken;\\n uint256 collateralFactor;\\n uint256 liquidationThreshold;\\n uint256 initialSupply;\\n address vTokenReceiver;\\n uint256 supplyCap;\\n uint256 borrowCap;\\n }\\n\\n uint256 internal constant MAX_POOL_NAME_LENGTH = 100;\\n\\n /**\\n * @notice Maps pool's comptroller address to metadata.\\n */\\n mapping(address => VenusPoolMetaData) public metadata;\\n\\n /**\\n * @dev Maps pool ID to pool's comptroller address\\n */\\n mapping(uint256 => address) private _poolsByID;\\n\\n /**\\n * @dev Total number of pools created.\\n */\\n uint256 private _numberOfPools;\\n\\n /**\\n * @dev Maps comptroller address to Venus pool Index.\\n */\\n mapping(address => VenusPool) private _poolByComptroller;\\n\\n /**\\n * @dev Maps pool's comptroller address to asset to vToken.\\n */\\n mapping(address => mapping(address => address)) private _vTokens;\\n\\n /**\\n * @dev Maps asset to list of supported pools.\\n */\\n mapping(address => address[]) private _supportedPools;\\n\\n /**\\n * @notice Emitted when a new Venus pool is added to the directory.\\n */\\n event PoolRegistered(address indexed comptroller, VenusPool pool);\\n\\n /**\\n * @notice Emitted when a pool name is set.\\n */\\n event PoolNameSet(address indexed comptroller, string oldName, string newName);\\n\\n /**\\n * @notice Emitted when a pool metadata is updated.\\n */\\n event PoolMetadataUpdated(\\n address indexed comptroller,\\n VenusPoolMetaData oldMetadata,\\n VenusPoolMetaData newMetadata\\n );\\n\\n /**\\n * @notice Emitted when a Market is added to the pool.\\n */\\n event MarketAdded(address indexed comptroller, address indexed vTokenAddress);\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializes the deployer to owner\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(address accessControlManager_) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n /**\\n * @notice Adds a new Venus pool to the directory\\n * @dev Price oracle must be configured before adding a pool\\n * @param name The name of the pool\\n * @param comptroller Pool's Comptroller contract\\n * @param closeFactor The pool's close factor (scaled by 1e18)\\n * @param liquidationIncentive The pool's liquidation incentive (scaled by 1e18)\\n * @param minLiquidatableCollateral Minimal collateral for regular (non-batch) liquidations flow\\n * @return index The index of the registered Venus pool\\n * @custom:error ZeroAddressNotAllowed is thrown when Comptroller address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when price oracle address is zero\\n */\\n function addPool(\\n string calldata name,\\n Comptroller comptroller,\\n uint256 closeFactor,\\n uint256 liquidationIncentive,\\n uint256 minLiquidatableCollateral\\n ) external virtual returns (uint256 index) {\\n _checkAccessAllowed(\\\"addPool(string,address,uint256,uint256,uint256)\\\");\\n // Input validation\\n ensureNonzeroAddress(address(comptroller));\\n ensureNonzeroAddress(address(comptroller.oracle()));\\n\\n uint256 poolId = _registerPool(name, address(comptroller));\\n\\n // Set Venus pool parameters\\n comptroller.setCloseFactor(closeFactor);\\n comptroller.setLiquidationIncentive(liquidationIncentive);\\n comptroller.setMinLiquidatableCollateral(minLiquidatableCollateral);\\n\\n return poolId;\\n }\\n\\n /**\\n * @notice Add a market to an existing pool and then mint to provide initial supply\\n * @param input The structure describing the parameters for adding a market to a pool\\n * @custom:error ZeroAddressNotAllowed is thrown when vToken address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when vTokenReceiver address is zero\\n */\\n function addMarket(AddMarketInput memory input) external {\\n _checkAccessAllowed(\\\"addMarket(AddMarketInput)\\\");\\n ensureNonzeroAddress(address(input.vToken));\\n ensureNonzeroAddress(input.vTokenReceiver);\\n require(input.initialSupply > 0, \\\"PoolRegistry: initialSupply is zero\\\");\\n\\n VToken vToken = input.vToken;\\n address vTokenAddress = address(vToken);\\n address comptrollerAddress = address(vToken.comptroller());\\n Comptroller comptroller = Comptroller(comptrollerAddress);\\n address underlyingAddress = vToken.underlying();\\n IERC20Upgradeable underlying = IERC20Upgradeable(underlyingAddress);\\n\\n require(_poolByComptroller[comptrollerAddress].creator != address(0), \\\"PoolRegistry: Pool not registered\\\");\\n // solhint-disable-next-line reason-string\\n require(\\n _vTokens[comptrollerAddress][underlyingAddress] == address(0),\\n \\\"PoolRegistry: Market already added for asset comptroller combination\\\"\\n );\\n\\n comptroller.supportMarket(vToken);\\n comptroller.setCollateralFactor(vToken, input.collateralFactor, input.liquidationThreshold);\\n\\n uint256[] memory newSupplyCaps = new uint256[](1);\\n uint256[] memory newBorrowCaps = new uint256[](1);\\n VToken[] memory vTokens = new VToken[](1);\\n\\n newSupplyCaps[0] = input.supplyCap;\\n newBorrowCaps[0] = input.borrowCap;\\n vTokens[0] = vToken;\\n\\n comptroller.setMarketSupplyCaps(vTokens, newSupplyCaps);\\n comptroller.setMarketBorrowCaps(vTokens, newBorrowCaps);\\n\\n _vTokens[comptrollerAddress][underlyingAddress] = vTokenAddress;\\n _supportedPools[underlyingAddress].push(comptrollerAddress);\\n\\n uint256 amountToSupply = _transferIn(underlying, msg.sender, input.initialSupply);\\n underlying.approve(vTokenAddress, 0);\\n underlying.approve(vTokenAddress, amountToSupply);\\n vToken.mintBehalf(input.vTokenReceiver, amountToSupply);\\n\\n emit MarketAdded(comptrollerAddress, vTokenAddress);\\n }\\n\\n /**\\n * @notice Modify existing Venus pool name\\n * @param comptroller Pool's Comptroller\\n * @param name New pool name\\n */\\n function setPoolName(address comptroller, string calldata name) external {\\n _checkAccessAllowed(\\\"setPoolName(address,string)\\\");\\n _ensureValidName(name);\\n VenusPool storage pool = _poolByComptroller[comptroller];\\n string memory oldName = pool.name;\\n pool.name = name;\\n emit PoolNameSet(comptroller, oldName, name);\\n }\\n\\n /**\\n * @notice Update metadata of an existing pool\\n * @param comptroller Pool's Comptroller\\n * @param metadata_ New pool metadata\\n */\\n function updatePoolMetadata(address comptroller, VenusPoolMetaData calldata metadata_) external {\\n _checkAccessAllowed(\\\"updatePoolMetadata(address,VenusPoolMetaData)\\\");\\n VenusPoolMetaData memory oldMetadata = metadata[comptroller];\\n metadata[comptroller] = metadata_;\\n emit PoolMetadataUpdated(comptroller, oldMetadata, metadata_);\\n }\\n\\n /**\\n * @notice Returns arrays of all Venus pools' data\\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\\n * @return A list of all pools within PoolRegistry, with details for each pool\\n */\\n function getAllPools() external view override returns (VenusPool[] memory) {\\n uint256 numberOfPools_ = _numberOfPools; // storage load to save gas\\n VenusPool[] memory _pools = new VenusPool[](numberOfPools_);\\n for (uint256 i = 1; i <= numberOfPools_; ++i) {\\n address comptroller = _poolsByID[i];\\n _pools[i - 1] = (_poolByComptroller[comptroller]);\\n }\\n return _pools;\\n }\\n\\n /**\\n * @param comptroller The comptroller proxy address associated to the pool\\n * @return Returns Venus pool\\n */\\n function getPoolByComptroller(address comptroller) external view override returns (VenusPool memory) {\\n return _poolByComptroller[comptroller];\\n }\\n\\n /**\\n * @param comptroller comptroller of Venus pool\\n * @return Returns Metadata of Venus pool\\n */\\n function getVenusPoolMetadata(address comptroller) external view override returns (VenusPoolMetaData memory) {\\n return metadata[comptroller];\\n }\\n\\n function getVTokenForAsset(address comptroller, address asset) external view override returns (address) {\\n return _vTokens[comptroller][asset];\\n }\\n\\n function getPoolsSupportedByAsset(address asset) external view override returns (address[] memory) {\\n return _supportedPools[asset];\\n }\\n\\n /**\\n * @dev Adds a new Venus pool to the directory (without checking msg.sender).\\n * @param name The name of the pool\\n * @param comptroller The pool's Comptroller proxy contract address\\n * @return The index of the registered Venus pool\\n */\\n function _registerPool(string calldata name, address comptroller) internal returns (uint256) {\\n VenusPool storage storedPool = _poolByComptroller[comptroller];\\n\\n require(storedPool.creator == address(0), \\\"PoolRegistry: Pool already exists in the directory.\\\");\\n _ensureValidName(name);\\n\\n ++_numberOfPools;\\n uint256 numberOfPools_ = _numberOfPools; // cache on stack to save storage read gas\\n\\n VenusPool memory pool = VenusPool(name, msg.sender, comptroller, block.number, block.timestamp);\\n\\n _poolsByID[numberOfPools_] = comptroller;\\n _poolByComptroller[comptroller] = pool;\\n\\n emit PoolRegistered(comptroller, pool);\\n return numberOfPools_;\\n }\\n\\n function _transferIn(\\n IERC20Upgradeable token,\\n address from,\\n uint256 amount\\n ) internal returns (uint256) {\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n return balanceAfter - balanceBefore;\\n }\\n\\n function _ensureValidName(string calldata name) internal pure {\\n require(bytes(name).length <= MAX_POOL_NAME_LENGTH, \\\"Pool's name is too large\\\");\\n }\\n}\\n\",\"keccak256\":\"0x6b903c298c9e2c3aaed29b4a1f76ace9fc24e50a48db22111bfc190a1a25c499\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title PoolRegistryInterface\\n * @author Venus\\n * @notice Interface implemented by `PoolRegistry`.\\n */\\ninterface PoolRegistryInterface {\\n /**\\n * @notice Struct for a Venus interest rate pool.\\n */\\n struct VenusPool {\\n string name;\\n address creator;\\n address comptroller;\\n uint256 blockPosted;\\n uint256 timestampPosted;\\n }\\n\\n /**\\n * @notice Struct for a Venus interest rate pool metadata.\\n */\\n struct VenusPoolMetaData {\\n string category;\\n string logoURL;\\n string description;\\n }\\n\\n /// @notice Get all pools in PoolRegistry\\n function getAllPools() external view returns (VenusPool[] memory);\\n\\n /// @notice Get a pool by comptroller address\\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\\n\\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\\n\\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\\n\\n /// @notice Get the metadata of a Pool by comptroller address\\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\\n}\\n\",\"keccak256\":\"0x7e8ccd190ef019a3f8c3fcb67ed3eadd7bed32b263f88566870d138cd95ae312\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n // The block number at which to stop rewards\\n uint32 lastRewardingBlock;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n /// @notice Emitted when a reward token last rewarding block for supply is updated\\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n */\\n function setLastRewardingBlocks(\\n VToken[] calldata vTokens,\\n uint32[] calldata supplyLastRewardingBlocks,\\n uint32[] calldata borrowLastRewardingBlocks\\n ) external {\\n _checkAccessAllowed(\\\"setLastRewardingBlock(address[],uint32[],uint32[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ) {\\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for a single market.\\n * @param vToken market's whose reward token last rewarding block to be updated\\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n */\\n function _setLastRewardingBlock(\\n VToken vToken,\\n uint32 supplyLastRewardingBlock,\\n uint32 borrowLastRewardingBlock\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n uint256 blockNumber = getBlockNumber();\\n\\n require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n require(\\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n require(\\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n\\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n }\\n\\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\\n blockNumber = supplyState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\\n blockNumber = borrowState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0x0e5bede4edc4346e689de0adcf98dc9642feb55d44c1916715741c5937a34d52\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IRiskFund.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IRiskFund\\n * @author Venus\\n * @notice Interface implemented by `RiskFund`.\\n */\\ninterface IRiskFund {\\n function swapPoolsAssets(\\n address[] calldata markets,\\n uint256[] calldata amountsOutMin,\\n address[][] calldata paths,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\\n\\n function updateAssetsState(address comptroller, address asset) external;\\n\\n function convertibleBaseAsset() external view returns (address);\\n\\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xa519791948d96fb81143cdd9db0a2b753a39f1f9ca4e8c68b92997e2095f241a\",\"license\":\"BSD-3-Clause\"},\"contracts/Shortfall/Shortfall.sol\":{\"content\":\"/// @notice SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { ReentrancyGuardUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { IRiskFund } from \\\"../RiskFund/IRiskFund.sol\\\";\\nimport { PoolRegistry } from \\\"../Pool/PoolRegistry.sol\\\";\\nimport { PoolRegistryInterface } from \\\"../Pool/PoolRegistryInterface.sol\\\";\\nimport { TokenDebtTracker } from \\\"../lib/TokenDebtTracker.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\nimport { EXP_SCALE } from \\\"../lib/constants.sol\\\";\\n\\n/**\\n * @title Shortfall\\n * @author Venus\\n * @notice Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset`\\n * is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value.\\n * This value is set and can be changed by the authorized accounts. If the pool\\u2019s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner\\n * is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise,\\n * if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the\\n * risk fund in exchange for paying off all the pool's bad debt.\\n */\\ncontract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGuardUpgradeable, TokenDebtTracker {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /// @notice Type of auction\\n enum AuctionType {\\n LARGE_POOL_DEBT,\\n LARGE_RISK_FUND\\n }\\n\\n /// @notice Status of auction\\n enum AuctionStatus {\\n NOT_STARTED,\\n STARTED,\\n ENDED\\n }\\n\\n /// @notice Auction metadata\\n struct Auction {\\n uint256 startBlock;\\n AuctionType auctionType;\\n AuctionStatus status;\\n VToken[] markets;\\n uint256 seizedRiskFund;\\n address highestBidder;\\n uint256 highestBidBps;\\n uint256 highestBidBlock;\\n uint256 startBidBps;\\n mapping(VToken => uint256) marketDebt;\\n mapping(VToken => uint256) bidAmount;\\n }\\n\\n /// @dev Max basis points i.e., 100%\\n uint256 private constant MAX_BPS = 10000;\\n\\n uint256 private constant DEFAULT_NEXT_BIDDER_BLOCK_LIMIT = 100;\\n\\n uint256 private constant DEFAULT_WAIT_FOR_FIRST_BIDDER = 100;\\n\\n uint256 private constant DEFAULT_INCENTIVE_BPS = 1000; // 10%\\n\\n /// @notice Pool registry address\\n address public poolRegistry;\\n\\n /// @notice Risk fund address\\n IRiskFund public riskFund;\\n\\n /// @notice Minimum USD debt in pool for shortfall to trigger\\n uint256 public minimumPoolBadDebt;\\n\\n /// @notice Incentive to auction participants, initial value set to 1000 or 10%\\n uint256 public incentiveBps;\\n\\n /// @notice Time to wait for next bidder. Initially waits for 100 blocks\\n uint256 public nextBidderBlockLimit;\\n\\n /// @notice Boolean of if auctions are paused\\n bool public auctionsPaused;\\n\\n /// @notice Time to wait for first bidder. Initially waits for 100 blocks\\n uint256 public waitForFirstBidder;\\n\\n /// @notice Auctions for each pool\\n mapping(address => Auction) public auctions;\\n\\n /// @notice Emitted when a auction starts\\n event AuctionStarted(\\n address indexed comptroller,\\n uint256 auctionStartBlock,\\n AuctionType auctionType,\\n VToken[] markets,\\n uint256[] marketsDebt,\\n uint256 seizedRiskFund,\\n uint256 startBidBps\\n );\\n\\n /// @notice Emitted when a bid is placed\\n event BidPlaced(address indexed comptroller, uint256 auctionStartBlock, uint256 bidBps, address indexed bidder);\\n\\n /// @notice Emitted when a auction is completed\\n event AuctionClosed(\\n address indexed comptroller,\\n uint256 auctionStartBlock,\\n address indexed highestBidder,\\n uint256 highestBidBps,\\n uint256 seizedRiskFind,\\n VToken[] markets,\\n uint256[] marketDebt\\n );\\n\\n /// @notice Emitted when a auction is restarted\\n event AuctionRestarted(address indexed comptroller, uint256 auctionStartBlock);\\n\\n /// @notice Emitted when pool registry address is updated\\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\\n\\n /// @notice Emitted when minimum pool bad debt is updated\\n event MinimumPoolBadDebtUpdated(uint256 oldMinimumPoolBadDebt, uint256 newMinimumPoolBadDebt);\\n\\n /// @notice Emitted when wait for first bidder block count is updated\\n event WaitForFirstBidderUpdated(uint256 oldWaitForFirstBidder, uint256 newWaitForFirstBidder);\\n\\n /// @notice Emitted when next bidder block limit is updated\\n event NextBidderBlockLimitUpdated(uint256 oldNextBidderBlockLimit, uint256 newNextBidderBlockLimit);\\n\\n /// @notice Emitted when incentiveBps is updated\\n event IncentiveBpsUpdated(uint256 oldIncentiveBps, uint256 newIncentiveBps);\\n\\n /// @notice Emitted when auctions are paused\\n event AuctionsPaused(address sender);\\n\\n /// @notice Emitted when auctions are unpaused\\n event AuctionsResumed(address sender);\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initialize the shortfall contract\\n * @param riskFund_ RiskFund contract address\\n * @param minimumPoolBadDebt_ Minimum bad debt in base asset for a pool to start auction\\n * @param accessControlManager_ AccessControlManager contract address\\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\\n */\\n function initialize(\\n IRiskFund riskFund_,\\n uint256 minimumPoolBadDebt_,\\n address accessControlManager_\\n ) external initializer {\\n ensureNonzeroAddress(address(riskFund_));\\n require(minimumPoolBadDebt_ != 0, \\\"invalid minimum pool bad debt\\\");\\n\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n __ReentrancyGuard_init();\\n __TokenDebtTracker_init();\\n minimumPoolBadDebt = minimumPoolBadDebt_;\\n riskFund = riskFund_;\\n waitForFirstBidder = DEFAULT_WAIT_FOR_FIRST_BIDDER;\\n nextBidderBlockLimit = DEFAULT_NEXT_BIDDER_BLOCK_LIMIT;\\n incentiveBps = DEFAULT_INCENTIVE_BPS;\\n auctionsPaused = false;\\n }\\n\\n /**\\n * @notice Place a bid greater than the previous in an ongoing auction\\n * @param comptroller Comptroller address of the pool\\n * @param bidBps The bid percent of the risk fund or bad debt depending on auction type\\n * @param auctionStartBlock The block number when auction started\\n * @custom:event Emits BidPlaced event on success\\n */\\n function placeBid(\\n address comptroller,\\n uint256 bidBps,\\n uint256 auctionStartBlock\\n ) external nonReentrant {\\n Auction storage auction = auctions[comptroller];\\n\\n require(auction.startBlock == auctionStartBlock, \\\"auction has been restarted\\\");\\n require(_isStarted(auction), \\\"no on-going auction\\\");\\n require(!_isStale(auction), \\\"auction is stale, restart it\\\");\\n require(bidBps > 0, \\\"basis points cannot be zero\\\");\\n require(bidBps <= MAX_BPS, \\\"basis points cannot be more than 10000\\\");\\n require(\\n (auction.auctionType == AuctionType.LARGE_POOL_DEBT &&\\n ((auction.highestBidder != address(0) && bidBps > auction.highestBidBps) ||\\n (auction.highestBidder == address(0) && bidBps >= auction.startBidBps))) ||\\n (auction.auctionType == AuctionType.LARGE_RISK_FUND &&\\n ((auction.highestBidder != address(0) && bidBps < auction.highestBidBps) ||\\n (auction.highestBidder == address(0) && bidBps <= auction.startBidBps))),\\n \\\"your bid is not the highest\\\"\\n );\\n\\n uint256 marketsCount = auction.markets.length;\\n for (uint256 i; i < marketsCount; ++i) {\\n VToken vToken = VToken(address(auction.markets[i]));\\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\\n\\n if (auction.highestBidder != address(0)) {\\n _transferOutOrTrackDebt(erc20, auction.highestBidder, auction.bidAmount[auction.markets[i]]);\\n }\\n uint256 balanceBefore = erc20.balanceOf(address(this));\\n\\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\\n uint256 currentBidAmount = ((auction.marketDebt[auction.markets[i]] * bidBps) / MAX_BPS);\\n erc20.safeTransferFrom(msg.sender, address(this), currentBidAmount);\\n } else {\\n erc20.safeTransferFrom(msg.sender, address(this), auction.marketDebt[auction.markets[i]]);\\n }\\n\\n uint256 balanceAfter = erc20.balanceOf(address(this));\\n auction.bidAmount[auction.markets[i]] = balanceAfter - balanceBefore;\\n }\\n\\n auction.highestBidder = msg.sender;\\n auction.highestBidBps = bidBps;\\n auction.highestBidBlock = block.number;\\n\\n emit BidPlaced(comptroller, auction.startBlock, bidBps, msg.sender);\\n }\\n\\n /**\\n * @notice Close an auction\\n * @param comptroller Comptroller address of the pool\\n * @custom:event Emits AuctionClosed event on successful close\\n */\\n function closeAuction(address comptroller) external nonReentrant {\\n Auction storage auction = auctions[comptroller];\\n\\n require(_isStarted(auction), \\\"no on-going auction\\\");\\n require(\\n block.number > auction.highestBidBlock + nextBidderBlockLimit && auction.highestBidder != address(0),\\n \\\"waiting for next bidder. cannot close auction\\\"\\n );\\n\\n uint256 marketsCount = auction.markets.length;\\n uint256[] memory marketsDebt = new uint256[](marketsCount);\\n\\n auction.status = AuctionStatus.ENDED;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n VToken vToken = VToken(address(auction.markets[i]));\\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\\n\\n uint256 balanceBefore = erc20.balanceOf(address(auction.markets[i]));\\n erc20.safeTransfer(address(auction.markets[i]), auction.bidAmount[auction.markets[i]]);\\n uint256 balanceAfter = erc20.balanceOf(address(auction.markets[i]));\\n marketsDebt[i] = balanceAfter - balanceBefore;\\n\\n auction.markets[i].badDebtRecovered(marketsDebt[i]);\\n }\\n\\n uint256 riskFundBidAmount;\\n\\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\\n riskFundBidAmount = auction.seizedRiskFund;\\n } else {\\n riskFundBidAmount = (auction.seizedRiskFund * auction.highestBidBps) / MAX_BPS;\\n }\\n\\n address convertibleBaseAsset = riskFund.convertibleBaseAsset();\\n\\n uint256 transferredAmount = riskFund.transferReserveForAuction(comptroller, riskFundBidAmount);\\n _transferOutOrTrackDebt(IERC20Upgradeable(convertibleBaseAsset), auction.highestBidder, riskFundBidAmount);\\n\\n emit AuctionClosed(\\n comptroller,\\n auction.startBlock,\\n auction.highestBidder,\\n auction.highestBidBps,\\n transferredAmount,\\n auction.markets,\\n marketsDebt\\n );\\n }\\n\\n /**\\n * @notice Start a auction when there is not currently one active\\n * @param comptroller Comptroller address of the pool\\n * @custom:event Emits AuctionStarted event on success\\n * @custom:event Errors if auctions are paused\\n */\\n function startAuction(address comptroller) external nonReentrant {\\n require(!auctionsPaused, \\\"Auctions are paused\\\");\\n _startAuction(comptroller);\\n }\\n\\n /**\\n * @notice Restart an auction\\n * @param comptroller Address of the pool\\n * @custom:event Emits AuctionRestarted event on successful restart\\n */\\n function restartAuction(address comptroller) external nonReentrant {\\n Auction storage auction = auctions[comptroller];\\n\\n require(!auctionsPaused, \\\"auctions are paused\\\");\\n require(_isStarted(auction), \\\"no on-going auction\\\");\\n require(_isStale(auction), \\\"you need to wait for more time for first bidder\\\");\\n\\n auction.status = AuctionStatus.ENDED;\\n\\n emit AuctionRestarted(comptroller, auction.startBlock);\\n _startAuction(comptroller);\\n }\\n\\n /**\\n * @notice Update next bidder block limit which is used determine when an auction can be closed\\n * @param _nextBidderBlockLimit New next bidder block limit\\n * @custom:event Emits NextBidderBlockLimitUpdated on success\\n * @custom:access Restricted by ACM\\n */\\n function updateNextBidderBlockLimit(uint256 _nextBidderBlockLimit) external {\\n _checkAccessAllowed(\\\"updateNextBidderBlockLimit(uint256)\\\");\\n require(_nextBidderBlockLimit != 0, \\\"_nextBidderBlockLimit must not be 0\\\");\\n uint256 oldNextBidderBlockLimit = nextBidderBlockLimit;\\n nextBidderBlockLimit = _nextBidderBlockLimit;\\n emit NextBidderBlockLimitUpdated(oldNextBidderBlockLimit, _nextBidderBlockLimit);\\n }\\n\\n /**\\n * @notice Updates the incentive BPS\\n * @param _incentiveBps New incentive BPS\\n * @custom:event Emits IncentiveBpsUpdated on success\\n * @custom:access Restricted by ACM\\n */\\n function updateIncentiveBps(uint256 _incentiveBps) external {\\n _checkAccessAllowed(\\\"updateIncentiveBps(uint256)\\\");\\n require(_incentiveBps != 0, \\\"incentiveBps must not be 0\\\");\\n uint256 oldIncentiveBps = incentiveBps;\\n incentiveBps = _incentiveBps;\\n emit IncentiveBpsUpdated(oldIncentiveBps, _incentiveBps);\\n }\\n\\n /**\\n * @notice Update minimum pool bad debt to start auction\\n * @param _minimumPoolBadDebt Minimum bad debt in BUSD for a pool to start auction\\n * @custom:event Emits MinimumPoolBadDebtUpdated on success\\n * @custom:access Restricted by ACM\\n */\\n function updateMinimumPoolBadDebt(uint256 _minimumPoolBadDebt) external {\\n _checkAccessAllowed(\\\"updateMinimumPoolBadDebt(uint256)\\\");\\n uint256 oldMinimumPoolBadDebt = minimumPoolBadDebt;\\n minimumPoolBadDebt = _minimumPoolBadDebt;\\n emit MinimumPoolBadDebtUpdated(oldMinimumPoolBadDebt, _minimumPoolBadDebt);\\n }\\n\\n /**\\n * @notice Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted\\n * @param _waitForFirstBidder New wait for first bidder block count\\n * @custom:event Emits WaitForFirstBidderUpdated on success\\n * @custom:access Restricted by ACM\\n */\\n function updateWaitForFirstBidder(uint256 _waitForFirstBidder) external {\\n _checkAccessAllowed(\\\"updateWaitForFirstBidder(uint256)\\\");\\n uint256 oldWaitForFirstBidder = waitForFirstBidder;\\n waitForFirstBidder = _waitForFirstBidder;\\n emit WaitForFirstBidderUpdated(oldWaitForFirstBidder, _waitForFirstBidder);\\n }\\n\\n /**\\n * @notice Update the pool registry this shortfall supports\\n * @dev After Pool Registry is deployed we need to set the pool registry address\\n * @param poolRegistry_ Address of pool registry contract\\n * @custom:event Emits PoolRegistryUpdated on success\\n * @custom:access Restricted to owner\\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n */\\n function updatePoolRegistry(address poolRegistry_) external onlyOwner {\\n ensureNonzeroAddress(poolRegistry_);\\n address oldPoolRegistry = poolRegistry;\\n poolRegistry = poolRegistry_;\\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\\n }\\n\\n /**\\n * @notice Pause auctions. This disables starting new auctions but lets the current auction finishes\\n * @custom:event Emits AuctionsPaused on success\\n * @custom:error Errors is auctions are paused\\n * @custom:access Restricted by ACM\\n */\\n function pauseAuctions() external {\\n _checkAccessAllowed(\\\"pauseAuctions()\\\");\\n require(!auctionsPaused, \\\"Auctions are already paused\\\");\\n auctionsPaused = true;\\n emit AuctionsPaused(msg.sender);\\n }\\n\\n /**\\n * @notice Resume paused auctions.\\n * @custom:event Emits AuctionsResumed on success\\n * @custom:error Errors is auctions are active\\n * @custom:access Restricted by ACM\\n */\\n function resumeAuctions() external {\\n _checkAccessAllowed(\\\"resumeAuctions()\\\");\\n require(auctionsPaused, \\\"Auctions are not paused\\\");\\n auctionsPaused = false;\\n emit AuctionsResumed(msg.sender);\\n }\\n\\n /**\\n * @notice Start a auction when there is not currently one active\\n * @param comptroller Comptroller address of the pool\\n */\\n function _startAuction(address comptroller) internal {\\n PoolRegistryInterface.VenusPool memory pool = PoolRegistry(poolRegistry).getPoolByComptroller(comptroller);\\n require(pool.comptroller == comptroller, \\\"comptroller doesn't exist pool registry\\\");\\n\\n Auction storage auction = auctions[comptroller];\\n require(\\n auction.status == AuctionStatus.NOT_STARTED || auction.status == AuctionStatus.ENDED,\\n \\\"auction is on-going\\\"\\n );\\n\\n auction.highestBidBps = 0;\\n auction.highestBidBlock = 0;\\n\\n uint256 marketsCount = auction.markets.length;\\n for (uint256 i; i < marketsCount; ++i) {\\n VToken vToken = auction.markets[i];\\n auction.marketDebt[vToken] = 0;\\n }\\n\\n delete auction.markets;\\n\\n VToken[] memory vTokens = _getAllMarkets(comptroller);\\n marketsCount = vTokens.length;\\n ResilientOracleInterface priceOracle = _getPriceOracle(comptroller);\\n uint256 poolBadDebt;\\n\\n uint256[] memory marketsDebt = new uint256[](marketsCount);\\n auction.markets = new VToken[](marketsCount);\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n uint256 marketBadDebt = vTokens[i].badDebt();\\n\\n priceOracle.updatePrice(address(vTokens[i]));\\n uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / EXP_SCALE;\\n\\n poolBadDebt = poolBadDebt + usdValue;\\n auction.markets[i] = vTokens[i];\\n auction.marketDebt[vTokens[i]] = marketBadDebt;\\n marketsDebt[i] = marketBadDebt;\\n }\\n\\n require(poolBadDebt >= minimumPoolBadDebt, \\\"pool bad debt is too low\\\");\\n\\n priceOracle.updateAssetPrice(riskFund.convertibleBaseAsset());\\n uint256 riskFundBalance = (priceOracle.getPrice(riskFund.convertibleBaseAsset()) *\\n riskFund.getPoolsBaseAssetReserves(comptroller)) / EXP_SCALE;\\n uint256 remainingRiskFundBalance = riskFundBalance;\\n uint256 badDebtPlusIncentive = poolBadDebt + ((poolBadDebt * incentiveBps) / MAX_BPS);\\n if (badDebtPlusIncentive >= riskFundBalance) {\\n auction.startBidBps =\\n (MAX_BPS * MAX_BPS * remainingRiskFundBalance) /\\n (poolBadDebt * (MAX_BPS + incentiveBps));\\n remainingRiskFundBalance = 0;\\n auction.auctionType = AuctionType.LARGE_POOL_DEBT;\\n } else {\\n uint256 maxSeizeableRiskFundBalance = badDebtPlusIncentive;\\n\\n remainingRiskFundBalance = remainingRiskFundBalance - maxSeizeableRiskFundBalance;\\n auction.auctionType = AuctionType.LARGE_RISK_FUND;\\n auction.startBidBps = MAX_BPS;\\n }\\n\\n auction.seizedRiskFund = riskFundBalance - remainingRiskFundBalance;\\n auction.startBlock = block.number;\\n auction.status = AuctionStatus.STARTED;\\n auction.highestBidder = address(0);\\n\\n emit AuctionStarted(\\n comptroller,\\n auction.startBlock,\\n auction.auctionType,\\n auction.markets,\\n marketsDebt,\\n auction.seizedRiskFund,\\n auction.startBidBps\\n );\\n }\\n\\n /**\\n * @dev Returns the price oracle of the pool\\n * @param comptroller Address of the pool's comptroller\\n * @return oracle The pool's price oracle\\n */\\n function _getPriceOracle(address comptroller) internal view returns (ResilientOracleInterface) {\\n return ResilientOracleInterface(ComptrollerViewInterface(comptroller).oracle());\\n }\\n\\n /**\\n * @dev Returns all markets of the pool\\n * @param comptroller Address of the pool's comptroller\\n * @return markets The pool's markets as VToken array\\n */\\n function _getAllMarkets(address comptroller) internal view returns (VToken[] memory) {\\n return ComptrollerInterface(comptroller).getAllMarkets();\\n }\\n\\n /**\\n * @dev Checks if the auction has started\\n * @param auction The auction to query the status for\\n * @return True if the auction has started\\n */\\n function _isStarted(Auction storage auction) internal view returns (bool) {\\n return auction.status == AuctionStatus.STARTED;\\n }\\n\\n /**\\n * @dev Checks if the auction is stale, i.e. there's no bidder and the auction\\n * was started more than waitForFirstBidder blocks ago.\\n * @param auction The auction to query the status for\\n * @return True if the auction is stale\\n */\\n function _isStale(Auction storage auction) internal view returns (bool) {\\n bool noBidder = auction.highestBidder == address(0);\\n return noBidder && (block.number > auction.startBlock + waitForFirstBidder);\\n }\\n}\\n\",\"keccak256\":\"0x7115bf0deaa643edc9d2e79052144f0d6f3fd58c6506888cbfabfca73e9911e4\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/TokenDebtTracker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.13;\\n\\nimport { Initializable } from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\n/**\\n * @title TokenDebtTracker\\n * @author Venus\\n * @notice TokenDebtTracker is an abstract contract that handles transfers _out_ of the inheriting contract.\\n * If there is an error transferring out (due to any reason, e.g. the token contract restricted the user from\\n * receiving incoming transfers), the amount is recorded as a debt that can be claimed later.\\n * @dev Note that the inheriting contract keeps some amount of users' tokens on its balance, so be careful when\\n * using balanceOf(address(this))!\\n */\\nabstract contract TokenDebtTracker is Initializable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /**\\n * @notice Mapping (IERC20Upgradeable token => (address user => uint256 amount)).\\n * Tracks failed transfers: when a token transfer fails, we record the\\n * amount of the transfer, so that the user can redeem this debt later.\\n */\\n mapping(IERC20Upgradeable => mapping(address => uint256)) public tokenDebt;\\n\\n /**\\n * @notice Mapping (IERC20Upgradeable token => uint256 amount) shows how many\\n * tokens the contract owes to all users. This is useful for accounting to\\n * understand how much of balanceOf(address(this)) is already owed to users.\\n */\\n mapping(IERC20Upgradeable => uint256) public totalTokenDebt;\\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 * @notice Emitted when the contract's debt to the user is increased due to a failed transfer\\n * @param token Token address\\n * @param user User address\\n * @param amount The amount of debt added\\n */\\n event TokenDebtAdded(address indexed token, address indexed user, uint256 amount);\\n\\n /**\\n * @notice Emitted when a user claims tokens that the contract owes them\\n * @param token Token address\\n * @param user User address\\n * @param amount The amount transferred\\n */\\n event TokenDebtClaimed(address indexed token, address indexed user, uint256 amount);\\n\\n /**\\n * @notice Thrown if the user tries to claim more tokens than they are owed\\n * @param token The token the user is trying to claim\\n * @param owedAmount The amount of tokens the contract owes to the user\\n * @param amount The amount of tokens the user is trying to claim\\n */\\n error InsufficientDebt(address token, address user, uint256 owedAmount, uint256 amount);\\n\\n /**\\n * @notice Thrown if trying to transfer more tokens than the contract currently has\\n * @param token The token the contract is trying to transfer\\n * @param recipient The recipient of the transfer\\n * @param amount The amount of tokens the contract is trying to transfer\\n * @param availableBalance The amount of tokens the contract currently has\\n */\\n error InsufficientBalance(address token, address recipient, uint256 amount, uint256 availableBalance);\\n\\n /**\\n * @notice Transfers the tokens we owe to msg.sender, if any\\n * @param token The token to claim\\n * @param amount_ The amount of tokens to claim (or max uint256 to claim all)\\n * @custom:error InsufficientDebt The contract doesn't have enough debt to the user\\n */\\n function claimTokenDebt(IERC20Upgradeable token, uint256 amount_) external {\\n uint256 owedAmount = tokenDebt[token][msg.sender];\\n uint256 amount = (amount_ == type(uint256).max ? owedAmount : amount_);\\n if (amount > owedAmount) {\\n revert InsufficientDebt(address(token), msg.sender, owedAmount, amount);\\n }\\n unchecked {\\n // Safe because we revert if amount > owedAmount above\\n tokenDebt[token][msg.sender] = owedAmount - amount;\\n }\\n totalTokenDebt[token] -= amount;\\n emit TokenDebtClaimed(address(token), msg.sender, amount);\\n token.safeTransfer(msg.sender, amount);\\n }\\n\\n // solhint-disable-next-line func-name-mixedcase\\n function __TokenDebtTracker_init() internal onlyInitializing {\\n __TokenDebtTracker_init_unchained();\\n }\\n\\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\\n function __TokenDebtTracker_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @dev Transfers tokens to the recipient if the contract has enough balance, or\\n * records the debt if the transfer fails due to reasons unrelated to the contract's\\n * balance (e.g. if the token forbids transfers to the recipient).\\n * @param token The token to transfer\\n * @param to The recipient of the transfer\\n * @param amount The amount to transfer\\n * @custom:error InsufficientBalance The contract doesn't have enough balance to transfer\\n */\\n function _transferOutOrTrackDebt(\\n IERC20Upgradeable token,\\n address to,\\n uint256 amount\\n ) internal {\\n uint256 balance = token.balanceOf(address(this));\\n if (balance < amount) {\\n revert InsufficientBalance(address(token), address(this), amount, balance);\\n }\\n _transferOutOrTrackDebtSkippingBalanceCheck(token, to, amount);\\n }\\n\\n /**\\n * @dev Transfers tokens to the recipient, or records the debt if the transfer fails\\n * due to any reason, including insufficient balance.\\n * @param token The token to transfer\\n * @param to The recipient of the transfer\\n * @param amount The amount to transfer\\n */\\n function _transferOutOrTrackDebtSkippingBalanceCheck(\\n IERC20Upgradeable token,\\n address to,\\n uint256 amount\\n ) internal {\\n // We can't use safeTransfer here because we can't try-catch internal calls\\n bool success = _tryTransferOut(token, to, amount);\\n if (!success) {\\n tokenDebt[token][to] += amount;\\n totalTokenDebt[token] += amount;\\n emit TokenDebtAdded(address(token), to, amount);\\n }\\n }\\n\\n /**\\n * @dev Either transfers tokens to the recepient or returns false. Supports tokens\\n * thet revert or return false to indicate failure, and the non-compliant ones\\n * that do not return any value.\\n * @param token The token to transfer\\n * @param to The recipient of the transfer\\n * @param amount The amount to transfer\\n * @return true if the transfer succeeded, false otherwise\\n */\\n function _tryTransferOut(\\n IERC20Upgradeable token,\\n address to,\\n uint256 amount\\n ) private returns (bool) {\\n bytes memory callData = abi.encodeCall(token.transfer, (to, amount));\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(callData);\\n return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\\n }\\n}\\n\",\"keccak256\":\"0xa6fdbe421f8644f481706f22e9f52d72425d62c22bc036d00d46d6dbc61d3776\",\"license\":\"MIT\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61379080620000f36000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c806376ee801711610104578063a23926e1116100a2578063c350a1b511610071578063c350a1b51461043a578063e30c39781461044d578063e630fee01461045e578063f2fde38b1461047157600080fd5b8063a23926e1146103e4578063ae8ddcb014610402578063afcff50f14610415578063b4a0bdf31461042957600080fd5b80637f9c714f116100de5780637f9c714f14610396578063892149a3146103c15780638da5cb5b146103cb57806391f8e694146103dc57600080fd5b806376ee80171461034f57806379ba5097146103625780637cf890301461036a57600080fd5b80634b34e5661161017c578063690d6a141161014b578063690d6a141461030a5780636f254c321461032a578063715018a61461033d57806373d73f401461034557600080fd5b80634b34e566146102c957806351b2fd01146102dc5780635be3fe1b146102ef57806367cd03ab146102f757600080fd5b80631d59410a116101b85780631d59410a1461021a578063264ad3d4146102945780634075fa0f146102ac578063438d33d7146102bf57600080fd5b806304717aca146101df5780630db011d0146101f45780630e32cb8614610207575b600080fd5b6101f26101ed366004612fcf565b610484565b005b6101f2610202366004613004565b610afb565b6101f2610215366004613004565b610c60565b610277610228366004613004565b610134602052600090815260409020805460018201546003830154600484015460058501546006860154600790960154949560ff8086169661010090960416946001600160a01b039093169288565b60405161028b98979695949392919061304b565b60405180910390f35b61029e61012f5481565b60405190815260200161028b565b6101f26102ba366004613004565b610c71565b61029e6101305481565b6101f26102d7366004613004565b610cd6565b6101f26102ea3660046130aa565b611300565b6101f2611368565b6101f26103053660046130aa565b61142d565b61029e610318366004613004565b60fc6020526000908152604090205481565b6101f26103383660046130aa565b6114fa565b6101f26115b6565b61029e6101315481565b6101f261035d3660046130c3565b6115ca565b6101f26116e3565b61012e5461037e906001600160a01b031681565b6040516001600160a01b03909116815260200161028b565b61029e6103a43660046130ef565b60fb60209081526000928352604080842090915290825290205481565b61029e6101335481565b6033546001600160a01b031661037e565b6101f261175a565b610132546103f29060ff1681565b604051901515815260200161028b565b6101f2610410366004613004565b61181c565b61012d5461037e906001600160a01b031681565b6097546001600160a01b031661037e565b6101f2610448366004613128565b611880565b6065546001600160a01b031661037e565b6101f261046c3660046130aa565b611a45565b6101f261047f366004613004565b611aa5565b61048c611b16565b6001600160a01b038316600090815261013460205260409020805482146104fa5760405162461bcd60e51b815260206004820152601a60248201527f61756374696f6e20686173206265656e2072657374617274656400000000000060448201526064015b60405180910390fd5b61050381611b6f565b61051f5760405162461bcd60e51b81526004016104f19061316a565b61052881611b97565b156105755760405162461bcd60e51b815260206004820152601c60248201527f61756374696f6e206973207374616c652c20726573746172742069740000000060448201526064016104f1565b600083116105c55760405162461bcd60e51b815260206004820152601b60248201527f626173697320706f696e74732063616e6e6f74206265207a65726f000000000060448201526064016104f1565b6127108311156106265760405162461bcd60e51b815260206004820152602660248201527f626173697320706f696e74732063616e6e6f74206265206d6f7265207468616e60448201526502031303030360d41b60648201526084016104f1565b600060018083015460ff169081111561064157610641613021565b14801561068d575060048101546001600160a01b0316158015906106685750806005015483115b8061068d575060048101546001600160a01b031615801561068d575080600701548310155b806106f8575060018181015460ff16818111156106ac576106ac613021565b1480156106f8575060048101546001600160a01b0316158015906106d35750806005015483105b806106f8575060048101546001600160a01b03161580156106f8575080600701548311155b6107445760405162461bcd60e51b815260206004820152601b60248201527f796f757220626964206973206e6f74207468652068696768657374000000000060448201526064016104f1565b600281015460005b81811015610a7f57600083600201828154811061076b5761076b613197565b600091825260208083209091015460408051636f307dc360e01b815290516001600160a01b0390921694508492636f307dc3926004808401938290030181865afa1580156107bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e191906131bd565b60048601549091506001600160a01b03161561085857610858818660040160009054906101000a90046001600160a01b031687600901600089600201888154811061082e5761082e613197565b60009182526020808320909101546001600160a01b03168352820192909252604001902054611bcb565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561089f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c391906131da565b9050600060018088015460ff16908111156108e0576108e0613021565b0361095c576000612710898860080160008a600201898154811061090657610906613197565b60009182526020808320909101546001600160a01b031683528201929092526040019020546109359190613209565b61093f9190613228565b90506109566001600160a01b038416333084611c83565b506109b1565b6109b133308860080160008a600201898154811061097c5761097c613197565b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902054908616929190611c83565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156109f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1c91906131da565b9050610a28828261324a565b876009016000896002018881548110610a4357610a43613197565b60009182526020808320909101546001600160a01b0316835282019290925260400190205550610a7892508391506132619050565b905061074c565b506004820180546001600160a01b0319163390811790915560058301859055436006840155825460408051918252602082018790526001600160a01b038816917f5485cf82060404805b51f48c0c4afa3cec4a9e5755c0131e1243553f0eebb9a3910160405180910390a35050610af6600160c955565b505050565b610b03611b16565b6001600160a01b0381166000908152610134602052604090206101325460ff1615610b665760405162461bcd60e51b8152602060048201526013602482015272185d58dd1a5bdb9cc8185c99481c185d5cd959606a1b60448201526064016104f1565b610b6f81611b6f565b610b8b5760405162461bcd60e51b81526004016104f19061316a565b610b9481611b97565b610bf85760405162461bcd60e51b815260206004820152602f60248201527f796f75206e65656420746f207761697420666f72206d6f72652074696d65206660448201526e37b9103334b939ba103134b23232b960891b60648201526084016104f1565b60018101805461ff001916610200179055805460408051918252516001600160a01b038416917faca104a4f0d6f116782afaefa8b644e86d53857ff9151824131b726b49a858d4919081900360200190a2610c5282611cf5565b50610c5d600160c955565b50565b610c68612694565b610c5d816126ee565b610c79611b16565b6101325460ff1615610cc35760405162461bcd60e51b8152602060048201526013602482015272105d58dd1a5bdb9cc8185c99481c185d5cd959606a1b60448201526064016104f1565b610ccc81611cf5565b610c5d600160c955565b610cde611b16565b6001600160a01b038116600090815261013460205260409020610d0081611b6f565b610d1c5760405162461bcd60e51b81526004016104f19061316a565b610131548160060154610d2f919061327a565b43118015610d49575060048101546001600160a01b031615155b610dab5760405162461bcd60e51b815260206004820152602d60248201527f77616974696e6720666f72206e657874206269646465722e2063616e6e6f742060448201526c31b637b9b29030bab1ba34b7b760991b60648201526084016104f1565b600281015460008167ffffffffffffffff811115610dcb57610dcb613292565b604051908082528060200260200182016040528015610df4578160200160208202803683370190505b5060018401805461ff001916610200179055905060005b8281101561113b576000846002018281548110610e2a57610e2a613197565b600091825260208083209091015460408051636f307dc360e01b815290516001600160a01b0390921694508492636f307dc3926004808401938290030181865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea091906131bd565b90506000816001600160a01b03166370a08231886002018681548110610ec857610ec8613197565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015610f18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3c91906131da565b9050610fc3876002018581548110610f5657610f56613197565b9060005260206000200160009054906101000a90046001600160a01b03168860090160008a6002018881548110610f8f57610f8f613197565b60009182526020808320909101546001600160a01b03908116845290830193909352604090910190205490851691906127ac565b6000826001600160a01b03166370a08231896002018781548110610fe957610fe9613197565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015611039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105d91906131da565b9050611069828261324a565b86868151811061107b5761107b613197565b60200260200101818152505087600201858154811061109c5761109c613197565b60009182526020909120015486516001600160a01b039091169063ef60450c908890889081106110ce576110ce613197565b60200260200101516040518263ffffffff1660e01b81526004016110f491815260200190565b600060405180830381600087803b15801561110e57600080fd5b505af1158015611122573d6000803e3d6000fd5b50505050505050508061113490613261565b9050610e0b565b5060008060018086015460ff169081111561115857611158613021565b036111685750600383015461118c565b6127108460050154856003015461117f9190613209565b6111899190613228565b90505b61012e546040805163c8ecc0d360e01b815290516000926001600160a01b03169163c8ecc0d39160048083019260209291908290030181865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb91906131bd565b61012e54604051630a9837c560e01b81526001600160a01b0389811660048301526024820186905292935060009290911690630a9837c5906044016020604051808303816000875af1158015611255573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127991906131da565b60048701549091506112969083906001600160a01b031685611bcb565b6004860154865460058801546040516001600160a01b03938416938b16927ff50338be3ffa7cdbebca76c758cfd1745fb4abe5bd3736c2dbf0cc6483a7b93f926112e892879060028e01908c90613321565b60405180910390a3505050505050610c5d600160c955565b6113216040518060600160405280602181526020016136f6602191396127dc565b61012f80549082905560408051828152602081018490527f85814f0246fcd999c88af70c9e6238211e79444ff07ec745b80aed19ddb268c891015b60405180910390a15050565b6113996040518060400160405280601081526020016f726573756d6541756374696f6e73282960801b8152506127dc565b6101325460ff166113ec5760405162461bcd60e51b815260206004820152601760248201527f41756374696f6e7320617265206e6f742070617573656400000000000000000060448201526064016104f1565b610132805460ff191690556040513381527f91b812e075fb9190eebe2d938c00a7179d150156469a467ec60a290035f4635a906020015b60405180910390a1565b61146b6040518060400160405280601b81526020017f757064617465496e63656e746976654270732875696e743235362900000000008152506127dc565b806000036114bb5760405162461bcd60e51b815260206004820152601a60248201527f696e63656e74697665427073206d757374206e6f74206265203000000000000060448201526064016104f1565b61013080549082905560408051828152602081018490527f3d438fa36c5052935d12a6925d1660c8150c74ef11ca672d4279bc6fd41b8bcf910161135c565b61151b604051806060016040528060238152602001613717602391396127dc565b806000036115775760405162461bcd60e51b815260206004820152602360248201527f5f6e657874426964646572426c6f636b4c696d6974206d757374206e6f74206260448201526206520360ec1b60648201526084016104f1565b61013180549082905560408051828152602081018490527f3f22dba09ee9845bd2be6926fea5337a0db935ca059cbb205d62174783e29664910161135c565b6115be612694565b6115c8600061287a565b565b6001600160a01b038216600090815260fb602090815260408083203384529091528120549060001983146115fe5782611600565b815b90508181111561164257604051639d2df25760e01b81526001600160a01b038516600482015233602482015260448101839052606481018290526084016104f1565b6001600160a01b038416600081815260fb602090815260408083203384528252808320858703905592825260fc9052908120805483929061168490849061324a565b909155505060405181815233906001600160a01b038616907f8d0aa4a41b0206123877a3705f51d17acf5f31dc241d24188abb2b881297ecfd9060200160405180910390a36116dd6001600160a01b03851633836127ac565b50505050565b60655433906001600160a01b031681146117515760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016104f1565b610c5d8161287a565b61178a6040518060400160405280600f81526020016e706175736541756374696f6e73282960881b8152506127dc565b6101325460ff16156117de5760405162461bcd60e51b815260206004820152601b60248201527f41756374696f6e732061726520616c726561647920706175736564000000000060448201526064016104f1565b610132805460ff191660011790556040513381527fc1be5163c9ebecf05bfbd6c6ae7c2b6ce2d3c43088dffaf5270cbf951615049990602001611423565b611824612694565b61182d81612893565b61012d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b600054610100900460ff16158080156118a05750600054600160ff909116105b806118ba5750303b1580156118ba575060005460ff166001145b61191d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104f1565b6000805460ff191660011790558015611940576000805461ff0019166101001790555b61194984612893565b826000036119995760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964206d696e696d756d20706f6f6c20626164206465627400000060448201526064016104f1565b6119a16128ba565b6119aa826128e9565b6119b2612910565b6119ba61293f565b61012f83905561012e80546001600160a01b0319166001600160a01b0386161790556064610133819055610131556103e861013055610132805460ff1916905580156116dd576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b611a6660405180606001604052806021815260200161373a602191396127dc565b61013380549082905560408051828152602081018490527f2a5be8a6b827e16c392d22522295794d6baff64565057a17b1f14c9d6c125a60910161135c565b611aad612694565b606580546001600160a01b0383166001600160a01b03199091168117909155611ade6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600260c95403611b685760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f1565b600260c955565b6000600180830154610100900460ff166002811115611b9057611b90613021565b1492915050565b60048101546000906001600160a01b031615808015611bc45750610133548354611bc1919061327a565b43115b9392505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015611c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3691906131da565b905081811015611c785760405163861da4bd60e01b81526001600160a01b038516600482015230602482015260448101839052606481018290526084016104f1565b6116dd84848461296e565b6040516001600160a01b03808516602483015283166044820152606481018290526116dd9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a40565b600160c955565b61012d54604051637aee632d60e01b81526001600160a01b0383811660048301526000921690637aee632d90602401600060405180830381865afa158015611d41573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d6991908101906133ea565b9050816001600160a01b031681604001516001600160a01b031614611de05760405162461bcd60e51b815260206004820152602760248201527f636f6d7074726f6c6c657220646f65736e277420657869737420706f6f6c20726044820152666567697374727960c81b60648201526084016104f1565b6001600160a01b038216600090815261013460205260408120906001820154610100900460ff166002811115611e1857611e18613021565b1480611e41575060026001820154610100900460ff166002811115611e3f57611e3f613021565b145b611e835760405162461bcd60e51b815260206004820152601360248201527261756374696f6e206973206f6e2d676f696e6760681b60448201526064016104f1565b600060058201819055600682018190556002820154905b81811015611eee576000836002018281548110611eb957611eb9613197565b60009182526020808320909101546001600160a01b03168252600886019052604081205550611ee781613261565b9050611e9a565b50611efd600283016000612f22565b6000611f0885612b15565b9050805191506000611f1986612b83565b90506000808467ffffffffffffffff811115611f3757611f37613292565b604051908082528060200260200182016040528015611f60578160200160208202803683370190505b5090508467ffffffffffffffff811115611f7c57611f7c613292565b604051908082528060200260200182016040528015611fa5578160200160208202803683370190505b508051611fbc916002890191602090910190612f40565b5060005b85811015612264576000858281518110611fdc57611fdc613197565b60200260200101516001600160a01b031663bbcac5576040518163ffffffff1660e01b8152600401602060405180830381865afa158015612021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204591906131da565b9050846001600160a01b03166396e85ced87848151811061206857612068613197565b60200260200101516040518263ffffffff1660e01b815260040161209b91906001600160a01b0391909116815260200190565b600060405180830381600087803b1580156120b557600080fd5b505af11580156120c9573d6000803e3d6000fd5b505050506000670de0b6b3a764000082876001600160a01b031663fc57d4df8a87815181106120fa576120fa613197565b60200260200101516040518263ffffffff1660e01b815260040161212d91906001600160a01b0391909116815260200190565b602060405180830381865afa15801561214a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216e91906131da565b6121789190613209565b6121829190613228565b905061218e818661327a565b94508683815181106121a2576121a2613197565b60200260200101518960020184815481106121bf576121bf613197565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508189600801600089868151811061220657612206613197565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508184848151811061224557612245613197565b60200260200101818152505050508061225d90613261565b9050611fc0565b5061012f548210156122b85760405162461bcd60e51b815260206004820152601860248201527f706f6f6c20626164206465627420697320746f6f206c6f77000000000000000060448201526064016104f1565b826001600160a01b031663b62cad6961012e60009054906101000a90046001600160a01b03166001600160a01b031663c8ecc0d36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561231b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233f91906131bd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b15801561238057600080fd5b505af1158015612394573d6000803e3d6000fd5b505061012e5460405163534de8cf60e11b81526001600160a01b038c8116600483015260009450670de0b6b3a764000093509091169063a69bd19e90602401602060405180830381865afa1580156123f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241491906131da565b856001600160a01b03166341976e0961012e60009054906101000a90046001600160a01b03166001600160a01b031663c8ecc0d36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249b91906131bd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156124df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250391906131da565b61250d9190613209565b6125179190613228565b90506000819050600061271061013054866125329190613209565b61253c9190613228565b612546908661327a565b90508281106125a4576101305461255f9061271061327a565b6125699086613209565b8261257661271080613209565b6125809190613209565b61258a9190613228565b60078a015560018901805460ff19169055600091506125cb565b806125af818461324a565b60018b8101805460ff1916909117905561271060078c01559250505b6125d5828461324a565b60038a01554389556001808a01805461ff00191661010083021790555060008960040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6001600160a01b03167f56c1f0c5ea96c78d614c0246b1915086a325f09ce15526bd5d69b50232d681328a600001548b60010160009054906101000a900460ff168c600201888e600301548f6007015460405161267f969594939291906134e0565b60405180910390a25050505050505050505050565b6033546001600160a01b031633146115c85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f1565b6001600160a01b0381166127525760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b60648201526084016104f1565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0910161135c565b6040516001600160a01b038316602482015260448101829052610af690849063a9059cbb60e01b90606401611cb7565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab9061280f903390869060040161355a565b602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612850919061357e565b90508061287657333083604051634a3fa29360e01b81526004016104f1939291906135a0565b5050565b606580546001600160a01b0319169055610c5d81612be7565b6001600160a01b038116610c5d576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff166128e15760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c39565b600054610100900460ff16610c685760405162461bcd60e51b81526004016104f1906135d5565b600054610100900460ff166129375760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c69565b600054610100900460ff166129665760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c90565b600061297b848484612cb7565b9050806116dd576001600160a01b03808516600090815260fb60209081526040808320938716835292905290812080548492906129b990849061327a565b90915550506001600160a01b038416600090815260fc6020526040812080548492906129e690849061327a565b92505081905550826001600160a01b0316846001600160a01b03167fca6abeb3233ce8fb0de841c83102849b2d4165b80c92c5627899a5148ab4650084604051612a3291815260200190565b60405180910390a350505050565b6000612a95826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612da29092919063ffffffff16565b9050805160001480612ab6575080806020019051810190612ab6919061357e565b610af65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016104f1565b6060816001600160a01b031663b0772d0b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015612b55573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b7d9190810190613620565b92915050565b6000816001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7d91906131bd565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16612c605760405162461bcd60e51b81526004016104f1906135d5565b6115c83361287a565b600054610100900460ff16611cee5760405162461bcd60e51b81526004016104f1906135d5565b600054610100900460ff166115c85760405162461bcd60e51b81526004016104f1906135d5565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283918291881690612d159085906136c6565b6000604051808303816000865af19150503d8060008114612d52576040519150601f19603f3d011682016040523d82523d6000602084013e612d57565b606091505b5091509150818015612d81575080511580612d81575080806020019051810190612d81919061357e565b8015612d9757506000876001600160a01b03163b115b979650505050505050565b6060612db18484600085612db9565b949350505050565b606082471015612e1a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016104f1565b600080866001600160a01b03168587604051612e3691906136c6565b60006040518083038185875af1925050503d8060008114612e73576040519150601f19603f3d011682016040523d82523d6000602084013e612e78565b606091505b5091509150612d978783838760608315612ef3578251600003612eec576001600160a01b0385163b612eec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f1565b5081612db1565b612db18383815115612f085781518083602001fd5b8060405162461bcd60e51b81526004016104f191906136e2565b5080546000825590600052602060002090810190610c5d9190612fa5565b828054828255906000526020600020908101928215612f95579160200282015b82811115612f9557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612f60565b50612fa1929150612fa5565b5090565b5b80821115612fa15760008155600101612fa6565b6001600160a01b0381168114610c5d57600080fd5b600080600060608486031215612fe457600080fd5b8335612fef81612fba565b95602085013595506040909401359392505050565b60006020828403121561301657600080fd5b8135611bc481612fba565b634e487b7160e01b600052602160045260246000fd5b6002811061304757613047613021565b9052565b8881526101008101613060602083018a613037565b6003881061307057613070613021565b604082019790975260608101959095526001600160a01b0393909316608085015260a084019190915260c083015260e09091015292915050565b6000602082840312156130bc57600080fd5b5035919050565b600080604083850312156130d657600080fd5b82356130e181612fba565b946020939093013593505050565b6000806040838503121561310257600080fd5b823561310d81612fba565b9150602083013561311d81612fba565b809150509250929050565b60008060006060848603121561313d57600080fd5b833561314881612fba565b925060208401359150604084013561315f81612fba565b809150509250925092565b60208082526013908201527237379037b716b3b7b4b7339030bab1ba34b7b760691b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b80516131b881612fba565b919050565b6000602082840312156131cf57600080fd5b8151611bc481612fba565b6000602082840312156131ec57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613223576132236131f3565b500290565b60008261324557634e487b7160e01b600052601260045260246000fd5b500490565b60008282101561325c5761325c6131f3565b500390565b600060018201613273576132736131f3565b5060010190565b6000821982111561328d5761328d6131f3565b500190565b634e487b7160e01b600052604160045260246000fd5b6000815480845260208085019450836000528060002060005b838110156132e65781546001600160a01b0316875295820195600191820191016132c1565b509495945050505050565b600081518084526020808501945080840160005b838110156132e657815187529582019590820190600101613305565b85815284602082015283604082015260a06060820152600061334660a08301856132a8565b828103608084015261335881856132f1565b98975050505050505050565b60405160a0810167ffffffffffffffff8111828210171561338757613387613292565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156133b6576133b6613292565b604052919050565b60005b838110156133d95781810151838201526020016133c1565b838111156116dd5750506000910152565b600060208083850312156133fd57600080fd5b825167ffffffffffffffff8082111561341557600080fd5b9084019060a0828703121561342957600080fd5b613431613364565b82518281111561344057600080fd5b8301601f8101881361345157600080fd5b80518381111561346357613463613292565b613475601f8201601f1916870161338d565b9350808452888682840101111561348b57600080fd5b61349a818786018885016133be565b50508181526134aa8484016131ad565b848201526134ba604084016131ad565b604082015260608301516060820152608083015160808201528094505050505092915050565b8681526134f06020820187613037565b60c06040820152600061350660c08301876132a8565b828103606084015261351881876132f1565b6080840195909552505060a00152949350505050565b600081518084526135468160208601602086016133be565b601f01601f19169290920160200192915050565b6001600160a01b0383168152604060208201819052600090612db19083018461352e565b60006020828403121561359057600080fd5b81518015158114611bc457600080fd5b6001600160a01b038481168252831660208201526060604082018190526000906135cc9083018461352e565b95945050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6000602080838503121561363357600080fd5b825167ffffffffffffffff8082111561364b57600080fd5b818501915085601f83011261365f57600080fd5b81518181111561367157613671613292565b8060051b915061368284830161338d565b818152918301840191848101908884111561369c57600080fd5b938501935b8385101561335857845192506136b683612fba565b82825293850193908501906136a1565b600082516136d88184602087016133be565b9190910192915050565b602081526000611bc4602083018461352e56fe7570646174654d696e696d756d506f6f6c426164446562742875696e74323536297570646174654e657874426964646572426c6f636b4c696d69742875696e743235362975706461746557616974466f7246697273744269646465722875696e7432353629a2646970667358221220cdd1210a9ea7d2dc0776d5d22df850b673565d10413487e9a45d7df9c7039cdf64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101da5760003560e01c806376ee801711610104578063a23926e1116100a2578063c350a1b511610071578063c350a1b51461043a578063e30c39781461044d578063e630fee01461045e578063f2fde38b1461047157600080fd5b8063a23926e1146103e4578063ae8ddcb014610402578063afcff50f14610415578063b4a0bdf31461042957600080fd5b80637f9c714f116100de5780637f9c714f14610396578063892149a3146103c15780638da5cb5b146103cb57806391f8e694146103dc57600080fd5b806376ee80171461034f57806379ba5097146103625780637cf890301461036a57600080fd5b80634b34e5661161017c578063690d6a141161014b578063690d6a141461030a5780636f254c321461032a578063715018a61461033d57806373d73f401461034557600080fd5b80634b34e566146102c957806351b2fd01146102dc5780635be3fe1b146102ef57806367cd03ab146102f757600080fd5b80631d59410a116101b85780631d59410a1461021a578063264ad3d4146102945780634075fa0f146102ac578063438d33d7146102bf57600080fd5b806304717aca146101df5780630db011d0146101f45780630e32cb8614610207575b600080fd5b6101f26101ed366004612fcf565b610484565b005b6101f2610202366004613004565b610afb565b6101f2610215366004613004565b610c60565b610277610228366004613004565b610134602052600090815260409020805460018201546003830154600484015460058501546006860154600790960154949560ff8086169661010090960416946001600160a01b039093169288565b60405161028b98979695949392919061304b565b60405180910390f35b61029e61012f5481565b60405190815260200161028b565b6101f26102ba366004613004565b610c71565b61029e6101305481565b6101f26102d7366004613004565b610cd6565b6101f26102ea3660046130aa565b611300565b6101f2611368565b6101f26103053660046130aa565b61142d565b61029e610318366004613004565b60fc6020526000908152604090205481565b6101f26103383660046130aa565b6114fa565b6101f26115b6565b61029e6101315481565b6101f261035d3660046130c3565b6115ca565b6101f26116e3565b61012e5461037e906001600160a01b031681565b6040516001600160a01b03909116815260200161028b565b61029e6103a43660046130ef565b60fb60209081526000928352604080842090915290825290205481565b61029e6101335481565b6033546001600160a01b031661037e565b6101f261175a565b610132546103f29060ff1681565b604051901515815260200161028b565b6101f2610410366004613004565b61181c565b61012d5461037e906001600160a01b031681565b6097546001600160a01b031661037e565b6101f2610448366004613128565b611880565b6065546001600160a01b031661037e565b6101f261046c3660046130aa565b611a45565b6101f261047f366004613004565b611aa5565b61048c611b16565b6001600160a01b038316600090815261013460205260409020805482146104fa5760405162461bcd60e51b815260206004820152601a60248201527f61756374696f6e20686173206265656e2072657374617274656400000000000060448201526064015b60405180910390fd5b61050381611b6f565b61051f5760405162461bcd60e51b81526004016104f19061316a565b61052881611b97565b156105755760405162461bcd60e51b815260206004820152601c60248201527f61756374696f6e206973207374616c652c20726573746172742069740000000060448201526064016104f1565b600083116105c55760405162461bcd60e51b815260206004820152601b60248201527f626173697320706f696e74732063616e6e6f74206265207a65726f000000000060448201526064016104f1565b6127108311156106265760405162461bcd60e51b815260206004820152602660248201527f626173697320706f696e74732063616e6e6f74206265206d6f7265207468616e60448201526502031303030360d41b60648201526084016104f1565b600060018083015460ff169081111561064157610641613021565b14801561068d575060048101546001600160a01b0316158015906106685750806005015483115b8061068d575060048101546001600160a01b031615801561068d575080600701548310155b806106f8575060018181015460ff16818111156106ac576106ac613021565b1480156106f8575060048101546001600160a01b0316158015906106d35750806005015483105b806106f8575060048101546001600160a01b03161580156106f8575080600701548311155b6107445760405162461bcd60e51b815260206004820152601b60248201527f796f757220626964206973206e6f74207468652068696768657374000000000060448201526064016104f1565b600281015460005b81811015610a7f57600083600201828154811061076b5761076b613197565b600091825260208083209091015460408051636f307dc360e01b815290516001600160a01b0390921694508492636f307dc3926004808401938290030181865afa1580156107bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e191906131bd565b60048601549091506001600160a01b03161561085857610858818660040160009054906101000a90046001600160a01b031687600901600089600201888154811061082e5761082e613197565b60009182526020808320909101546001600160a01b03168352820192909252604001902054611bcb565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561089f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c391906131da565b9050600060018088015460ff16908111156108e0576108e0613021565b0361095c576000612710898860080160008a600201898154811061090657610906613197565b60009182526020808320909101546001600160a01b031683528201929092526040019020546109359190613209565b61093f9190613228565b90506109566001600160a01b038416333084611c83565b506109b1565b6109b133308860080160008a600201898154811061097c5761097c613197565b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902054908616929190611c83565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156109f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1c91906131da565b9050610a28828261324a565b876009016000896002018881548110610a4357610a43613197565b60009182526020808320909101546001600160a01b0316835282019290925260400190205550610a7892508391506132619050565b905061074c565b506004820180546001600160a01b0319163390811790915560058301859055436006840155825460408051918252602082018790526001600160a01b038816917f5485cf82060404805b51f48c0c4afa3cec4a9e5755c0131e1243553f0eebb9a3910160405180910390a35050610af6600160c955565b505050565b610b03611b16565b6001600160a01b0381166000908152610134602052604090206101325460ff1615610b665760405162461bcd60e51b8152602060048201526013602482015272185d58dd1a5bdb9cc8185c99481c185d5cd959606a1b60448201526064016104f1565b610b6f81611b6f565b610b8b5760405162461bcd60e51b81526004016104f19061316a565b610b9481611b97565b610bf85760405162461bcd60e51b815260206004820152602f60248201527f796f75206e65656420746f207761697420666f72206d6f72652074696d65206660448201526e37b9103334b939ba103134b23232b960891b60648201526084016104f1565b60018101805461ff001916610200179055805460408051918252516001600160a01b038416917faca104a4f0d6f116782afaefa8b644e86d53857ff9151824131b726b49a858d4919081900360200190a2610c5282611cf5565b50610c5d600160c955565b50565b610c68612694565b610c5d816126ee565b610c79611b16565b6101325460ff1615610cc35760405162461bcd60e51b8152602060048201526013602482015272105d58dd1a5bdb9cc8185c99481c185d5cd959606a1b60448201526064016104f1565b610ccc81611cf5565b610c5d600160c955565b610cde611b16565b6001600160a01b038116600090815261013460205260409020610d0081611b6f565b610d1c5760405162461bcd60e51b81526004016104f19061316a565b610131548160060154610d2f919061327a565b43118015610d49575060048101546001600160a01b031615155b610dab5760405162461bcd60e51b815260206004820152602d60248201527f77616974696e6720666f72206e657874206269646465722e2063616e6e6f742060448201526c31b637b9b29030bab1ba34b7b760991b60648201526084016104f1565b600281015460008167ffffffffffffffff811115610dcb57610dcb613292565b604051908082528060200260200182016040528015610df4578160200160208202803683370190505b5060018401805461ff001916610200179055905060005b8281101561113b576000846002018281548110610e2a57610e2a613197565b600091825260208083209091015460408051636f307dc360e01b815290516001600160a01b0390921694508492636f307dc3926004808401938290030181865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea091906131bd565b90506000816001600160a01b03166370a08231886002018681548110610ec857610ec8613197565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015610f18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3c91906131da565b9050610fc3876002018581548110610f5657610f56613197565b9060005260206000200160009054906101000a90046001600160a01b03168860090160008a6002018881548110610f8f57610f8f613197565b60009182526020808320909101546001600160a01b03908116845290830193909352604090910190205490851691906127ac565b6000826001600160a01b03166370a08231896002018781548110610fe957610fe9613197565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015611039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105d91906131da565b9050611069828261324a565b86868151811061107b5761107b613197565b60200260200101818152505087600201858154811061109c5761109c613197565b60009182526020909120015486516001600160a01b039091169063ef60450c908890889081106110ce576110ce613197565b60200260200101516040518263ffffffff1660e01b81526004016110f491815260200190565b600060405180830381600087803b15801561110e57600080fd5b505af1158015611122573d6000803e3d6000fd5b50505050505050508061113490613261565b9050610e0b565b5060008060018086015460ff169081111561115857611158613021565b036111685750600383015461118c565b6127108460050154856003015461117f9190613209565b6111899190613228565b90505b61012e546040805163c8ecc0d360e01b815290516000926001600160a01b03169163c8ecc0d39160048083019260209291908290030181865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb91906131bd565b61012e54604051630a9837c560e01b81526001600160a01b0389811660048301526024820186905292935060009290911690630a9837c5906044016020604051808303816000875af1158015611255573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127991906131da565b60048701549091506112969083906001600160a01b031685611bcb565b6004860154865460058801546040516001600160a01b03938416938b16927ff50338be3ffa7cdbebca76c758cfd1745fb4abe5bd3736c2dbf0cc6483a7b93f926112e892879060028e01908c90613321565b60405180910390a3505050505050610c5d600160c955565b6113216040518060600160405280602181526020016136f6602191396127dc565b61012f80549082905560408051828152602081018490527f85814f0246fcd999c88af70c9e6238211e79444ff07ec745b80aed19ddb268c891015b60405180910390a15050565b6113996040518060400160405280601081526020016f726573756d6541756374696f6e73282960801b8152506127dc565b6101325460ff166113ec5760405162461bcd60e51b815260206004820152601760248201527f41756374696f6e7320617265206e6f742070617573656400000000000000000060448201526064016104f1565b610132805460ff191690556040513381527f91b812e075fb9190eebe2d938c00a7179d150156469a467ec60a290035f4635a906020015b60405180910390a1565b61146b6040518060400160405280601b81526020017f757064617465496e63656e746976654270732875696e743235362900000000008152506127dc565b806000036114bb5760405162461bcd60e51b815260206004820152601a60248201527f696e63656e74697665427073206d757374206e6f74206265203000000000000060448201526064016104f1565b61013080549082905560408051828152602081018490527f3d438fa36c5052935d12a6925d1660c8150c74ef11ca672d4279bc6fd41b8bcf910161135c565b61151b604051806060016040528060238152602001613717602391396127dc565b806000036115775760405162461bcd60e51b815260206004820152602360248201527f5f6e657874426964646572426c6f636b4c696d6974206d757374206e6f74206260448201526206520360ec1b60648201526084016104f1565b61013180549082905560408051828152602081018490527f3f22dba09ee9845bd2be6926fea5337a0db935ca059cbb205d62174783e29664910161135c565b6115be612694565b6115c8600061287a565b565b6001600160a01b038216600090815260fb602090815260408083203384529091528120549060001983146115fe5782611600565b815b90508181111561164257604051639d2df25760e01b81526001600160a01b038516600482015233602482015260448101839052606481018290526084016104f1565b6001600160a01b038416600081815260fb602090815260408083203384528252808320858703905592825260fc9052908120805483929061168490849061324a565b909155505060405181815233906001600160a01b038616907f8d0aa4a41b0206123877a3705f51d17acf5f31dc241d24188abb2b881297ecfd9060200160405180910390a36116dd6001600160a01b03851633836127ac565b50505050565b60655433906001600160a01b031681146117515760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016104f1565b610c5d8161287a565b61178a6040518060400160405280600f81526020016e706175736541756374696f6e73282960881b8152506127dc565b6101325460ff16156117de5760405162461bcd60e51b815260206004820152601b60248201527f41756374696f6e732061726520616c726561647920706175736564000000000060448201526064016104f1565b610132805460ff191660011790556040513381527fc1be5163c9ebecf05bfbd6c6ae7c2b6ce2d3c43088dffaf5270cbf951615049990602001611423565b611824612694565b61182d81612893565b61012d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b600054610100900460ff16158080156118a05750600054600160ff909116105b806118ba5750303b1580156118ba575060005460ff166001145b61191d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104f1565b6000805460ff191660011790558015611940576000805461ff0019166101001790555b61194984612893565b826000036119995760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964206d696e696d756d20706f6f6c20626164206465627400000060448201526064016104f1565b6119a16128ba565b6119aa826128e9565b6119b2612910565b6119ba61293f565b61012f83905561012e80546001600160a01b0319166001600160a01b0386161790556064610133819055610131556103e861013055610132805460ff1916905580156116dd576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b611a6660405180606001604052806021815260200161373a602191396127dc565b61013380549082905560408051828152602081018490527f2a5be8a6b827e16c392d22522295794d6baff64565057a17b1f14c9d6c125a60910161135c565b611aad612694565b606580546001600160a01b0383166001600160a01b03199091168117909155611ade6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600260c95403611b685760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f1565b600260c955565b6000600180830154610100900460ff166002811115611b9057611b90613021565b1492915050565b60048101546000906001600160a01b031615808015611bc45750610133548354611bc1919061327a565b43115b9392505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015611c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3691906131da565b905081811015611c785760405163861da4bd60e01b81526001600160a01b038516600482015230602482015260448101839052606481018290526084016104f1565b6116dd84848461296e565b6040516001600160a01b03808516602483015283166044820152606481018290526116dd9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a40565b600160c955565b61012d54604051637aee632d60e01b81526001600160a01b0383811660048301526000921690637aee632d90602401600060405180830381865afa158015611d41573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d6991908101906133ea565b9050816001600160a01b031681604001516001600160a01b031614611de05760405162461bcd60e51b815260206004820152602760248201527f636f6d7074726f6c6c657220646f65736e277420657869737420706f6f6c20726044820152666567697374727960c81b60648201526084016104f1565b6001600160a01b038216600090815261013460205260408120906001820154610100900460ff166002811115611e1857611e18613021565b1480611e41575060026001820154610100900460ff166002811115611e3f57611e3f613021565b145b611e835760405162461bcd60e51b815260206004820152601360248201527261756374696f6e206973206f6e2d676f696e6760681b60448201526064016104f1565b600060058201819055600682018190556002820154905b81811015611eee576000836002018281548110611eb957611eb9613197565b60009182526020808320909101546001600160a01b03168252600886019052604081205550611ee781613261565b9050611e9a565b50611efd600283016000612f22565b6000611f0885612b15565b9050805191506000611f1986612b83565b90506000808467ffffffffffffffff811115611f3757611f37613292565b604051908082528060200260200182016040528015611f60578160200160208202803683370190505b5090508467ffffffffffffffff811115611f7c57611f7c613292565b604051908082528060200260200182016040528015611fa5578160200160208202803683370190505b508051611fbc916002890191602090910190612f40565b5060005b85811015612264576000858281518110611fdc57611fdc613197565b60200260200101516001600160a01b031663bbcac5576040518163ffffffff1660e01b8152600401602060405180830381865afa158015612021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204591906131da565b9050846001600160a01b03166396e85ced87848151811061206857612068613197565b60200260200101516040518263ffffffff1660e01b815260040161209b91906001600160a01b0391909116815260200190565b600060405180830381600087803b1580156120b557600080fd5b505af11580156120c9573d6000803e3d6000fd5b505050506000670de0b6b3a764000082876001600160a01b031663fc57d4df8a87815181106120fa576120fa613197565b60200260200101516040518263ffffffff1660e01b815260040161212d91906001600160a01b0391909116815260200190565b602060405180830381865afa15801561214a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216e91906131da565b6121789190613209565b6121829190613228565b905061218e818661327a565b94508683815181106121a2576121a2613197565b60200260200101518960020184815481106121bf576121bf613197565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508189600801600089868151811061220657612206613197565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508184848151811061224557612245613197565b60200260200101818152505050508061225d90613261565b9050611fc0565b5061012f548210156122b85760405162461bcd60e51b815260206004820152601860248201527f706f6f6c20626164206465627420697320746f6f206c6f77000000000000000060448201526064016104f1565b826001600160a01b031663b62cad6961012e60009054906101000a90046001600160a01b03166001600160a01b031663c8ecc0d36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561231b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233f91906131bd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b15801561238057600080fd5b505af1158015612394573d6000803e3d6000fd5b505061012e5460405163534de8cf60e11b81526001600160a01b038c8116600483015260009450670de0b6b3a764000093509091169063a69bd19e90602401602060405180830381865afa1580156123f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241491906131da565b856001600160a01b03166341976e0961012e60009054906101000a90046001600160a01b03166001600160a01b031663c8ecc0d36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249b91906131bd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156124df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250391906131da565b61250d9190613209565b6125179190613228565b90506000819050600061271061013054866125329190613209565b61253c9190613228565b612546908661327a565b90508281106125a4576101305461255f9061271061327a565b6125699086613209565b8261257661271080613209565b6125809190613209565b61258a9190613228565b60078a015560018901805460ff19169055600091506125cb565b806125af818461324a565b60018b8101805460ff1916909117905561271060078c01559250505b6125d5828461324a565b60038a01554389556001808a01805461ff00191661010083021790555060008960040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6001600160a01b03167f56c1f0c5ea96c78d614c0246b1915086a325f09ce15526bd5d69b50232d681328a600001548b60010160009054906101000a900460ff168c600201888e600301548f6007015460405161267f969594939291906134e0565b60405180910390a25050505050505050505050565b6033546001600160a01b031633146115c85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f1565b6001600160a01b0381166127525760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b60648201526084016104f1565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0910161135c565b6040516001600160a01b038316602482015260448101829052610af690849063a9059cbb60e01b90606401611cb7565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab9061280f903390869060040161355a565b602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612850919061357e565b90508061287657333083604051634a3fa29360e01b81526004016104f1939291906135a0565b5050565b606580546001600160a01b0319169055610c5d81612be7565b6001600160a01b038116610c5d576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff166128e15760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c39565b600054610100900460ff16610c685760405162461bcd60e51b81526004016104f1906135d5565b600054610100900460ff166129375760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c69565b600054610100900460ff166129665760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c90565b600061297b848484612cb7565b9050806116dd576001600160a01b03808516600090815260fb60209081526040808320938716835292905290812080548492906129b990849061327a565b90915550506001600160a01b038416600090815260fc6020526040812080548492906129e690849061327a565b92505081905550826001600160a01b0316846001600160a01b03167fca6abeb3233ce8fb0de841c83102849b2d4165b80c92c5627899a5148ab4650084604051612a3291815260200190565b60405180910390a350505050565b6000612a95826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612da29092919063ffffffff16565b9050805160001480612ab6575080806020019051810190612ab6919061357e565b610af65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016104f1565b6060816001600160a01b031663b0772d0b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015612b55573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b7d9190810190613620565b92915050565b6000816001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7d91906131bd565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16612c605760405162461bcd60e51b81526004016104f1906135d5565b6115c83361287a565b600054610100900460ff16611cee5760405162461bcd60e51b81526004016104f1906135d5565b600054610100900460ff166115c85760405162461bcd60e51b81526004016104f1906135d5565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283918291881690612d159085906136c6565b6000604051808303816000865af19150503d8060008114612d52576040519150601f19603f3d011682016040523d82523d6000602084013e612d57565b606091505b5091509150818015612d81575080511580612d81575080806020019051810190612d81919061357e565b8015612d9757506000876001600160a01b03163b115b979650505050505050565b6060612db18484600085612db9565b949350505050565b606082471015612e1a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016104f1565b600080866001600160a01b03168587604051612e3691906136c6565b60006040518083038185875af1925050503d8060008114612e73576040519150601f19603f3d011682016040523d82523d6000602084013e612e78565b606091505b5091509150612d978783838760608315612ef3578251600003612eec576001600160a01b0385163b612eec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f1565b5081612db1565b612db18383815115612f085781518083602001fd5b8060405162461bcd60e51b81526004016104f191906136e2565b5080546000825590600052602060002090810190610c5d9190612fa5565b828054828255906000526020600020908101928215612f95579160200282015b82811115612f9557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612f60565b50612fa1929150612fa5565b5090565b5b80821115612fa15760008155600101612fa6565b6001600160a01b0381168114610c5d57600080fd5b600080600060608486031215612fe457600080fd5b8335612fef81612fba565b95602085013595506040909401359392505050565b60006020828403121561301657600080fd5b8135611bc481612fba565b634e487b7160e01b600052602160045260246000fd5b6002811061304757613047613021565b9052565b8881526101008101613060602083018a613037565b6003881061307057613070613021565b604082019790975260608101959095526001600160a01b0393909316608085015260a084019190915260c083015260e09091015292915050565b6000602082840312156130bc57600080fd5b5035919050565b600080604083850312156130d657600080fd5b82356130e181612fba565b946020939093013593505050565b6000806040838503121561310257600080fd5b823561310d81612fba565b9150602083013561311d81612fba565b809150509250929050565b60008060006060848603121561313d57600080fd5b833561314881612fba565b925060208401359150604084013561315f81612fba565b809150509250925092565b60208082526013908201527237379037b716b3b7b4b7339030bab1ba34b7b760691b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b80516131b881612fba565b919050565b6000602082840312156131cf57600080fd5b8151611bc481612fba565b6000602082840312156131ec57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613223576132236131f3565b500290565b60008261324557634e487b7160e01b600052601260045260246000fd5b500490565b60008282101561325c5761325c6131f3565b500390565b600060018201613273576132736131f3565b5060010190565b6000821982111561328d5761328d6131f3565b500190565b634e487b7160e01b600052604160045260246000fd5b6000815480845260208085019450836000528060002060005b838110156132e65781546001600160a01b0316875295820195600191820191016132c1565b509495945050505050565b600081518084526020808501945080840160005b838110156132e657815187529582019590820190600101613305565b85815284602082015283604082015260a06060820152600061334660a08301856132a8565b828103608084015261335881856132f1565b98975050505050505050565b60405160a0810167ffffffffffffffff8111828210171561338757613387613292565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156133b6576133b6613292565b604052919050565b60005b838110156133d95781810151838201526020016133c1565b838111156116dd5750506000910152565b600060208083850312156133fd57600080fd5b825167ffffffffffffffff8082111561341557600080fd5b9084019060a0828703121561342957600080fd5b613431613364565b82518281111561344057600080fd5b8301601f8101881361345157600080fd5b80518381111561346357613463613292565b613475601f8201601f1916870161338d565b9350808452888682840101111561348b57600080fd5b61349a818786018885016133be565b50508181526134aa8484016131ad565b848201526134ba604084016131ad565b604082015260608301516060820152608083015160808201528094505050505092915050565b8681526134f06020820187613037565b60c06040820152600061350660c08301876132a8565b828103606084015261351881876132f1565b6080840195909552505060a00152949350505050565b600081518084526135468160208601602086016133be565b601f01601f19169290920160200192915050565b6001600160a01b0383168152604060208201819052600090612db19083018461352e565b60006020828403121561359057600080fd5b81518015158114611bc457600080fd5b6001600160a01b038481168252831660208201526060604082018190526000906135cc9083018461352e565b95945050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6000602080838503121561363357600080fd5b825167ffffffffffffffff8082111561364b57600080fd5b818501915085601f83011261365f57600080fd5b81518181111561367157613671613292565b8060051b915061368284830161338d565b818152918301840191848101908884111561369c57600080fd5b938501935b8385101561335857845192506136b683612fba565b82825293850193908501906136a1565b600082516136d88184602087016133be565b9190910192915050565b602081526000611bc4602083018461352e56fe7570646174654d696e696d756d506f6f6c426164446562742875696e74323536297570646174654e657874426964646572426c6f636b4c696d69742875696e743235362975706461746557616974466f7246697273744269646465722875696e7432353629a2646970667358221220cdd1210a9ea7d2dc0776d5d22df850b673565d10413487e9a45d7df9c7039cdf64736f6c634300080d0033", + "devdoc": { + "author": "Venus", + "errors": { + "InsufficientBalance(address,address,uint256,uint256)": [ + { + "params": { + "amount": "The amount of tokens the contract is trying to transfer", + "availableBalance": "The amount of tokens the contract currently has", + "recipient": "The recipient of the transfer", + "token": "The token the contract is trying to transfer" + } + } + ], + "InsufficientDebt(address,address,uint256,uint256)": [ + { + "params": { + "amount": "The amount of tokens the user is trying to claim", + "owedAmount": "The amount of tokens the contract owes to the user", + "token": "The token the user is trying to claim" + } + } + ] + }, + "kind": "dev", + "methods": { + "acceptOwnership()": { + "details": "The new owner accepts the ownership transfer." + }, + "claimTokenDebt(address,uint256)": { + "custom:error": "InsufficientDebt The contract doesn't have enough debt to the user", + "params": { + "amount_": "The amount of tokens to claim (or max uint256 to claim all)", + "token": "The token to claim" + } + }, + "closeAuction(address)": { + "custom:event": "Emits AuctionClosed event on successful close", + "params": { + "comptroller": "Comptroller address of the pool" + } + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "initialize(address,uint256,address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when convertible base asset address is zeroZeroAddressNotAllowed is thrown when risk fund address is zero", + "params": { + "accessControlManager_": "AccessControlManager contract address", + "minimumPoolBadDebt_": "Minimum bad debt in base asset for a pool to start auction", + "riskFund_": "RiskFund contract address" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pauseAuctions()": { + "custom:access": "Restricted by ACM", + "custom:error": "Errors is auctions are paused", + "custom:event": "Emits AuctionsPaused on success" + }, + "pendingOwner()": { + "details": "Returns the address of the pending owner." + }, + "placeBid(address,uint256,uint256)": { + "custom:event": "Emits BidPlaced event on success", + "params": { + "auctionStartBlock": "The block number when auction started", + "bidBps": "The bid percent of the risk fund or bad debt depending on auction type", + "comptroller": "Comptroller address of the pool" + } + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "restartAuction(address)": { + "custom:event": "Emits AuctionRestarted event on successful restart", + "params": { + "comptroller": "Address of the pool" + } + }, + "resumeAuctions()": { + "custom:access": "Restricted by ACM", + "custom:error": "Errors is auctions are active", + "custom:event": "Emits AuctionsResumed on success" + }, + "setAccessControlManager(address)": { + "custom:access": "Only Governance", + "custom:event": "Emits NewAccessControlManager event", + "details": "Admin function to set address of AccessControlManager", + "params": { + "accessControlManager_": "The new address of the AccessControlManager" + } + }, + "startAuction(address)": { + "custom:event": "Emits AuctionStarted event on successErrors if auctions are paused", + "params": { + "comptroller": "Comptroller address of the pool" + } + }, + "transferOwnership(address)": { + "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." + }, + "updateIncentiveBps(uint256)": { + "custom:access": "Restricted by ACM", + "custom:event": "Emits IncentiveBpsUpdated on success", + "params": { + "_incentiveBps": "New incentive BPS" + } + }, + "updateMinimumPoolBadDebt(uint256)": { + "custom:access": "Restricted by ACM", + "custom:event": "Emits MinimumPoolBadDebtUpdated on success", + "params": { + "_minimumPoolBadDebt": "Minimum bad debt in BUSD for a pool to start auction" + } + }, + "updateNextBidderBlockLimit(uint256)": { + "custom:access": "Restricted by ACM", + "custom:event": "Emits NextBidderBlockLimitUpdated on success", + "params": { + "_nextBidderBlockLimit": "New next bidder block limit" + } + }, + "updatePoolRegistry(address)": { + "custom:access": "Restricted to owner", + "custom:error": "ZeroAddressNotAllowed is thrown when pool registry address is zero", + "custom:event": "Emits PoolRegistryUpdated on success", + "details": "After Pool Registry is deployed we need to set the pool registry address", + "params": { + "poolRegistry_": "Address of pool registry contract" + } + }, + "updateWaitForFirstBidder(uint256)": { + "custom:access": "Restricted by ACM", + "custom:event": "Emits WaitForFirstBidderUpdated on success", + "params": { + "_waitForFirstBidder": "New wait for first bidder block count" + } + } + }, + "stateVariables": { + "MAX_BPS": { + "details": "Max basis points i.e., 100%" + } + }, + "title": "Shortfall", + "version": 1 + }, + "userdoc": { + "errors": { + "InsufficientBalance(address,address,uint256,uint256)": [ + { + "notice": "Thrown if trying to transfer more tokens than the contract currently has" + } + ], + "InsufficientDebt(address,address,uint256,uint256)": [ + { + "notice": "Thrown if the user tries to claim more tokens than they are owed" + } + ], + "Unauthorized(address,address,string)": [ + { + "notice": "Thrown when the action is prohibited by AccessControlManager" + } + ], + "ZeroAddressNotAllowed()": [ + { + "notice": "Thrown if the supplied address is a zero address where it is not allowed" + } + ] + }, + "events": { + "AuctionClosed(address,uint256,address,uint256,uint256,address[],uint256[])": { + "notice": "Emitted when a auction is completed" + }, + "AuctionRestarted(address,uint256)": { + "notice": "Emitted when a auction is restarted" + }, + "AuctionStarted(address,uint256,uint8,address[],uint256[],uint256,uint256)": { + "notice": "Emitted when a auction starts" + }, + "AuctionsPaused(address)": { + "notice": "Emitted when auctions are paused" + }, + "AuctionsResumed(address)": { + "notice": "Emitted when auctions are unpaused" + }, + "BidPlaced(address,uint256,uint256,address)": { + "notice": "Emitted when a bid is placed" + }, + "IncentiveBpsUpdated(uint256,uint256)": { + "notice": "Emitted when incentiveBps is updated" + }, + "MinimumPoolBadDebtUpdated(uint256,uint256)": { + "notice": "Emitted when minimum pool bad debt is updated" + }, + "NewAccessControlManager(address,address)": { + "notice": "Emitted when access control manager contract address is changed" + }, + "NextBidderBlockLimitUpdated(uint256,uint256)": { + "notice": "Emitted when next bidder block limit is updated" + }, + "PoolRegistryUpdated(address,address)": { + "notice": "Emitted when pool registry address is updated" + }, + "TokenDebtAdded(address,address,uint256)": { + "notice": "Emitted when the contract's debt to the user is increased due to a failed transfer" + }, + "TokenDebtClaimed(address,address,uint256)": { + "notice": "Emitted when a user claims tokens that the contract owes them" + }, + "WaitForFirstBidderUpdated(uint256,uint256)": { + "notice": "Emitted when wait for first bidder block count is updated" + } + }, + "kind": "user", + "methods": { + "accessControlManager()": { + "notice": "Returns the address of the access control manager contract" + }, + "auctions(address)": { + "notice": "Auctions for each pool" + }, + "auctionsPaused()": { + "notice": "Boolean of if auctions are paused" + }, + "claimTokenDebt(address,uint256)": { + "notice": "Transfers the tokens we owe to msg.sender, if any" + }, + "closeAuction(address)": { + "notice": "Close an auction" + }, + "incentiveBps()": { + "notice": "Incentive to auction participants, initial value set to 1000 or 10%" + }, + "initialize(address,uint256,address)": { + "notice": "Initialize the shortfall contract" + }, + "minimumPoolBadDebt()": { + "notice": "Minimum USD debt in pool for shortfall to trigger" + }, + "nextBidderBlockLimit()": { + "notice": "Time to wait for next bidder. Initially waits for 100 blocks" + }, + "pauseAuctions()": { + "notice": "Pause auctions. This disables starting new auctions but lets the current auction finishes" + }, + "placeBid(address,uint256,uint256)": { + "notice": "Place a bid greater than the previous in an ongoing auction" + }, + "poolRegistry()": { + "notice": "Pool registry address" + }, + "restartAuction(address)": { + "notice": "Restart an auction" + }, + "resumeAuctions()": { + "notice": "Resume paused auctions." + }, + "riskFund()": { + "notice": "Risk fund address" + }, + "setAccessControlManager(address)": { + "notice": "Sets the address of AccessControlManager" + }, + "startAuction(address)": { + "notice": "Start a auction when there is not currently one active" + }, + "tokenDebt(address,address)": { + "notice": "Mapping (IERC20Upgradeable token => (address user => uint256 amount)). Tracks failed transfers: when a token transfer fails, we record the amount of the transfer, so that the user can redeem this debt later." + }, + "totalTokenDebt(address)": { + "notice": "Mapping (IERC20Upgradeable token => uint256 amount) shows how many tokens the contract owes to all users. This is useful for accounting to understand how much of balanceOf(address(this)) is already owed to users." + }, + "updateIncentiveBps(uint256)": { + "notice": "Updates the incentive BPS" + }, + "updateMinimumPoolBadDebt(uint256)": { + "notice": "Update minimum pool bad debt to start auction" + }, + "updateNextBidderBlockLimit(uint256)": { + "notice": "Update next bidder block limit which is used determine when an auction can be closed" + }, + "updatePoolRegistry(address)": { + "notice": "Update the pool registry this shortfall supports" + }, + "updateWaitForFirstBidder(uint256)": { + "notice": "Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted" + }, + "waitForFirstBidder()": { + "notice": "Time to wait for first bidder. Initially waits for 100 blocks" + } + }, + "notice": "Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset` is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value. This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise, if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the risk fund in exchange for paying off all the pool's bad debt.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 290, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 293, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1397, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 162, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 282, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 71, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_pendingOwner", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 150, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 3341, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_accessControlManager", + "offset": 0, + "slot": "151", + "type": "t_contract(IAccessControlManagerV8)3525" + }, + { + "astId": 3346, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 466, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_status", + "offset": 0, + "slot": "201", + "type": "t_uint256" + }, + { + "astId": 535, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 19411, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "tokenDebt", + "offset": 0, + "slot": "251", + "type": "t_mapping(t_contract(IERC20Upgradeable)614,t_mapping(t_address,t_uint256))" + }, + { + "astId": 19417, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "totalTokenDebt", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_contract(IERC20Upgradeable)614,t_uint256)" + }, + { + "astId": 19422, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "253", + "type": "t_array(t_uint256)48_storage" + }, + { + "astId": 14516, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "poolRegistry", + "offset": 0, + "slot": "301", + "type": "t_address" + }, + { + "astId": 14520, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "riskFund", + "offset": 0, + "slot": "302", + "type": "t_contract(IRiskFund)13073" + }, + { + "astId": 14523, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "minimumPoolBadDebt", + "offset": 0, + "slot": "303", + "type": "t_uint256" + }, + { + "astId": 14526, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "incentiveBps", + "offset": 0, + "slot": "304", + "type": "t_uint256" + }, + { + "astId": 14529, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "nextBidderBlockLimit", + "offset": 0, + "slot": "305", + "type": "t_uint256" + }, + { + "astId": 14532, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "auctionsPaused", + "offset": 0, + "slot": "306", + "type": "t_bool" + }, + { + "astId": 14535, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "waitForFirstBidder", + "offset": 0, + "slot": "307", + "type": "t_uint256" + }, + { + "astId": 14541, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "auctions", + "offset": 0, + "slot": "308", + "type": "t_mapping(t_address,t_struct(Auction)14500_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_contract(VToken)18767)dyn_storage": { + "base": "t_contract(VToken)18767", + "encoding": "dynamic_array", + "label": "contract VToken[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)48_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[48]", + "numberOfBytes": "1536" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IAccessControlManagerV8)3525": { + "encoding": "inplace", + "label": "contract IAccessControlManagerV8", + "numberOfBytes": "20" + }, + "t_contract(IERC20Upgradeable)614": { + "encoding": "inplace", + "label": "contract IERC20Upgradeable", + "numberOfBytes": "20" + }, + "t_contract(IRiskFund)13073": { + "encoding": "inplace", + "label": "contract IRiskFund", + "numberOfBytes": "20" + }, + "t_contract(VToken)18767": { + "encoding": "inplace", + "label": "contract VToken", + "numberOfBytes": "20" + }, + "t_enum(AuctionStatus)14467": { + "encoding": "inplace", + "label": "enum Shortfall.AuctionStatus", + "numberOfBytes": "1" + }, + "t_enum(AuctionType)14463": { + "encoding": "inplace", + "label": "enum Shortfall.AuctionType", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_struct(Auction)14500_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct Shortfall.Auction)", + "numberOfBytes": "32", + "value": "t_struct(Auction)14500_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_contract(IERC20Upgradeable)614,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_contract(IERC20Upgradeable)614", + "label": "mapping(contract IERC20Upgradeable => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_contract(IERC20Upgradeable)614,t_uint256)": { + "encoding": "mapping", + "key": "t_contract(IERC20Upgradeable)614", + "label": "mapping(contract IERC20Upgradeable => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_contract(VToken)18767,t_uint256)": { + "encoding": "mapping", + "key": "t_contract(VToken)18767", + "label": "mapping(contract VToken => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(Auction)14500_storage": { + "encoding": "inplace", + "label": "struct Shortfall.Auction", + "members": [ + { + "astId": 14469, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "startBlock", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 14472, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "auctionType", + "offset": 0, + "slot": "1", + "type": "t_enum(AuctionType)14463" + }, + { + "astId": 14475, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "status", + "offset": 1, + "slot": "1", + "type": "t_enum(AuctionStatus)14467" + }, + { + "astId": 14479, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "markets", + "offset": 0, + "slot": "2", + "type": "t_array(t_contract(VToken)18767)dyn_storage" + }, + { + "astId": 14481, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "seizedRiskFund", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 14483, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "highestBidder", + "offset": 0, + "slot": "4", + "type": "t_address" + }, + { + "astId": 14485, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "highestBidBps", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 14487, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "highestBidBlock", + "offset": 0, + "slot": "6", + "type": "t_uint256" + }, + { + "astId": 14489, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "startBidBps", + "offset": 0, + "slot": "7", + "type": "t_uint256" + }, + { + "astId": 14494, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "marketDebt", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_contract(VToken)18767,t_uint256)" + }, + { + "astId": 14499, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "bidAmount", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_contract(VToken)18767,t_uint256)" + } + ], + "numberOfBytes": "320" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} diff --git a/deployments/bscmainnet/Shortfall_Proxy.json b/deployments/bscmainnet/Shortfall_Proxy.json new file mode 100644 index 000000000..a10a3adc4 --- /dev/null +++ b/deployments/bscmainnet/Shortfall_Proxy.json @@ -0,0 +1,267 @@ +{ + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "receipt": { + "to": null, + "from": "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D", + "contractAddress": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "transactionIndex": 44, + "gasUsed": "933014", + "logsBloom": "0x00000000010000000000000000000000400000000000000000800000000000000000000000000000000000000000000000200000000000000000000000009000000000000000000400000000000002000001000000000000000000000000000000000000030000000000000000000800000000800000002000000000000000400000000000000000000000000000000000000000000080000000000000800000000000000000000000000000000400000000040000800000000000000000000000000020000000000000000000040000000000000400000000000000001020000000000000000000000000000000004000000800000000000000000000000000", + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b", + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000916e607af3250ecb2fd4ea82a37eb2756a20e1fc" + ], + "data": "0x", + "logIndex": 95, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + }, + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000055a9f5374af30e3045fb491f1da3c2e8a74d168d" + ], + "data": "0x", + "logIndex": 96, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + }, + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555", + "logIndex": 97, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + }, + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 98, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + }, + { + "transactionIndex": 44, + "blockNumber": 31670900, + "transactionHash": "0x16dc489401afc0948250f6e03f035ec6ba625f8cd74f6792b8ad069994af5b37", + "address": "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006beb6d2695b67feb73ad4f172e8e2975497187e4", + "logIndex": 99, + "blockHash": "0x63df0568d865129b7a82a8bb98b42154a8e4cc4dbcdac2926f42d452c46a742b" + } + ], + "blockNumber": 31670900, + "cumulativeGasUsed": "4614383", + "status": 1, + "byzantium": true + }, + "args": [ + "0x916e607AF3250ECB2Fd4ea82A37Eb2756A20e1fC", + "0x6beb6D2695B67FEb73ad4f172E8E2975497187e4", + "0xc350a1b5000000000000000000000000df31a28d68a2ab381d42b380649ead7ae2a76e4200000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000004788629abc6cfca10f9f969efdeaa1cf70c23555" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bscmainnet/solcInputs/394b060e0e484d4aa39aea929deecf07.json b/deployments/bscmainnet/solcInputs/394b060e0e484d4aa39aea929deecf07.json new file mode 100644 index 000000000..9e6416284 --- /dev/null +++ b/deployments/bscmainnet/solcInputs/394b060e0e484d4aa39aea929deecf07.json @@ -0,0 +1,210 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides 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} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\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" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\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" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20Upgradeable 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\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. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\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[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\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 {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\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 * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\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 * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\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 revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\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 * _Available since v3.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\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 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 */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title Venus Access Control Contract.\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\n * The contract allows the owner to set an AccessControlManager contract address.\n * It can restrict method calls based on the sender's role and the method's signature.\n */\n\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\n /// @notice Access control manager contract\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\n error Unauthorized(address sender, address calledContract, string methodSignature);\n\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n }\n\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Sets the address of AccessControlManager\n * @dev Admin function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n * @custom:event Emits NewAccessControlManager event\n * @custom:access Only Governance\n */\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Returns the address of the access control manager contract\n */\n function accessControlManager() external view returns (IAccessControlManagerV8) {\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\n }\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title Venus Access Control Contract\n * @author venus\n * @dev This contract is a wrapper of OpenZeppelin AccessControl\n *\t\textending it in a way to standartize access control\n *\t\twithin Venus Smart Contract Ecosystem\n */\ncontract AccessControlManager is AccessControl, IAccessControlManagerV8 {\n /// @notice Emitted when an account is given a permission to a certain contract function\n /// @dev If contract address is 0x000..0 this means that the account is a default admin of this function and\n /// can call any contract function with this signature\n event PermissionGranted(address account, address contractAddress, string functionSig);\n\n /// @notice Emitted when an account is revoked a permission to a certain contract function\n event PermissionRevoked(address account, address contractAddress, string functionSig);\n\n constructor() {\n // Grant the contract deployer the default admin role: it will be able\n // to grant and revoke any roles\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\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 * @param contractAddress address of contract for which call permissions will be granted\n * @dev if contractAddress is zero address, the account can access the specified function\n * on **any** contract managed by this ACL\n * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n * @param accountToPermit account that will be given access to the contract function\n * @custom:event Emits a {RoleGranted} and {PermissionGranted} events.\n */\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n grantRole(role, accountToPermit);\n emit PermissionGranted(accountToPermit, contractAddress, functionSig);\n }\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(uint256,bool)\"\n * @custom:event Emits {RoleRevoked} and {PermissionRevoked} events.\n */\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n revokeRole(role, accountToRevoke);\n emit PermissionRevoked(accountToRevoke, contractAddress, functionSig);\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev Since restricted contracts using this function as a permission hook, we can get contracts address with msg.sender\n * @param account for which call permissions will be checked\n * @param functionSig restricted function signature e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n *\n */\n function isAllowedToCall(address account, string calldata functionSig) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(msg.sender, functionSig));\n\n if (hasRole(role, account)) {\n return true;\n } else {\n role = keccak256(abi.encodePacked(address(0), functionSig));\n return hasRole(role, account);\n }\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev This function is used as a view function to check permissions rather than contract hook for access restriction check.\n * @param account for which call permissions will be checked against\n * @param contractAddress address of the restricted contract\n * @param functionSig signature of the restricted function e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n */\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n return hasRole(role, account);\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\ninterface IAccessControlManagerV8 is IAccessControl {\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\n\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) external;\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/oracle/contracts/interfaces/FeedRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface FeedRegistryInterface {\n function latestRoundDataByName(\n string memory base,\n string memory quote\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function decimalsByName(string memory base, string memory quote) external view returns (uint8);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface OracleInterface {\n function getPrice(address asset) external view returns (uint256);\n}\n\ninterface ResilientOracleInterface is OracleInterface {\n function updatePrice(address vToken) external;\n\n function updateAssetPrice(address asset) external;\n\n function getUnderlyingPrice(address vToken) external view returns (uint256);\n}\n\ninterface TwapInterface is OracleInterface {\n function updateTwap(address asset) external returns (uint256);\n}\n\ninterface BoundValidatorInterface {\n function validatePriceWithAnchorPrice(\n address asset,\n uint256 reporterPrice,\n uint256 anchorPrice\n ) external view returns (bool);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/PublicResolverInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity 0.8.13;\n\ninterface PublicResolverInterface {\n function addr(bytes32 node) external view returns (address payable);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/SIDRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity 0.8.13;\n\ninterface SIDRegistryInterface {\n function resolver(bytes32 node) external view returns (address);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/VBep20Interface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface VBep20Interface is IERC20Metadata {\n /**\n * @notice Underlying asset for this VToken\n */\n function underlying() external view returns (address);\n}\n" + }, + "@venusprotocol/oracle/contracts/oracles/BinanceOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/SIDRegistryInterface.sol\";\nimport \"../interfaces/FeedRegistryInterface.sol\";\nimport \"../interfaces/PublicResolverInterface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport \"../interfaces/OracleInterface.sol\";\n\n/**\n * @title BinanceOracle\n * @author Venus\n * @notice This oracle fetches price of assets from Binance.\n */\ncontract BinanceOracle is AccessControlledV8, OracleInterface {\n address public sidRegistryAddress;\n\n /// @notice Set this as asset address for BNB. This is the underlying address for vBNB\n address public constant BNB_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n /// @notice Max stale period configuration for assets\n mapping(string => uint256) public maxStalePeriod;\n\n /// @notice Override symbols to be compatible with Binance feed registry\n mapping(string => string) public symbols;\n\n event MaxStalePeriodAdded(string indexed asset, uint256 maxStalePeriod);\n\n event SymbolOverridden(string indexed symbol, string overriddenSymbol);\n\n /**\n * @notice Checks whether an address is null or not\n */\n modifier notNullAddress(address someone) {\n if (someone == address(0)) revert(\"can't be zero address\");\n _;\n }\n\n /// @notice Constructor for the implementation contract.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Used to set the max stale period of an asset\n * @param symbol The symbol of the asset\n * @param _maxStalePeriod The max stake period\n */\n function setMaxStalePeriod(string memory symbol, uint256 _maxStalePeriod) external {\n _checkAccessAllowed(\"setMaxStalePeriod(string,uint256)\");\n if (_maxStalePeriod == 0) revert(\"stale period can't be zero\");\n if (bytes(symbol).length == 0) revert(\"symbol cannot be empty\");\n\n maxStalePeriod[symbol] = _maxStalePeriod;\n emit MaxStalePeriodAdded(symbol, _maxStalePeriod);\n }\n\n /**\n * @notice Used to override a symbol when fetching price\n * @param symbol The symbol to override\n * @param overrideSymbol The symbol after override\n */\n function setSymbolOverride(string calldata symbol, string calldata overrideSymbol) external {\n _checkAccessAllowed(\"setSymbolOverride(string,string)\");\n if (bytes(symbol).length == 0) revert(\"symbol cannot be empty\");\n\n symbols[symbol] = overrideSymbol;\n emit SymbolOverridden(symbol, overrideSymbol);\n }\n\n /**\n * @notice Sets the contracts required to fetch prices\n * @param _sidRegistryAddress Address of SID registry\n * @param _accessControlManager Address of the access control manager contract\n */\n function initialize(\n address _sidRegistryAddress,\n address _accessControlManager\n ) external initializer notNullAddress(_sidRegistryAddress) {\n sidRegistryAddress = _sidRegistryAddress;\n __AccessControlled_init(_accessControlManager);\n }\n\n /**\n * @notice Uses Space ID to fetch the feed registry address\n * @return feedRegistryAddress Address of binance oracle feed registry.\n */\n function getFeedRegistryAddress() public view returns (address) {\n bytes32 nodeHash = 0x94fe3821e0768eb35012484db4df61890f9a6ca5bfa984ef8ff717e73139faff;\n\n SIDRegistryInterface sidRegistry = SIDRegistryInterface(sidRegistryAddress);\n address publicResolverAddress = sidRegistry.resolver(nodeHash);\n PublicResolverInterface publicResolver = PublicResolverInterface(publicResolverAddress);\n\n return publicResolver.addr(nodeHash);\n }\n\n /**\n * @notice Gets the price of a asset from the binance oracle\n * @param asset Address of the asset\n * @return Price in USD\n */\n function getPrice(address asset) public view returns (uint256) {\n string memory symbol;\n uint256 decimals;\n\n if (asset == BNB_ADDR) {\n symbol = \"BNB\";\n decimals = 18;\n } else {\n IERC20Metadata token = IERC20Metadata(asset);\n symbol = token.symbol();\n decimals = token.decimals();\n }\n\n string memory overrideSymbol = symbols[symbol];\n\n if (bytes(overrideSymbol).length != 0) {\n symbol = overrideSymbol;\n }\n\n return _getPrice(symbol, decimals);\n }\n\n function _getPrice(string memory symbol, uint256 decimals) internal view returns (uint256) {\n FeedRegistryInterface feedRegistry = FeedRegistryInterface(getFeedRegistryAddress());\n\n (, int256 answer, , uint256 updatedAt, ) = feedRegistry.latestRoundDataByName(symbol, \"USD\");\n if (answer <= 0) revert(\"invalid binance oracle price\");\n if (block.timestamp < updatedAt) revert(\"updatedAt exceeds block time\");\n\n uint256 deltaTime;\n unchecked {\n deltaTime = block.timestamp - updatedAt;\n }\n if (deltaTime > maxStalePeriod[symbol]) revert(\"binance oracle price expired\");\n\n uint256 decimalDelta = feedRegistry.decimalsByName(symbol, \"USD\");\n return (uint256(answer) * (10 ** (18 - decimalDelta))) * (10 ** (18 - decimals));\n }\n}\n" + }, + "@venusprotocol/oracle/contracts/oracles/ChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\n/**\n * @title ChainlinkOracle\n * @author Venus\n * @notice This oracle fetches prices of assets from the Chainlink oracle.\n */\ncontract ChainlinkOracle is AccessControlledV8, OracleInterface {\n struct TokenConfig {\n /// @notice Underlying token address, which can't be a null address\n /// @notice Used to check if a token is supported\n /// @notice 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB for BNB\n address asset;\n /// @notice Chainlink feed address\n address feed;\n /// @notice Price expiration period of this asset\n uint256 maxStalePeriod;\n }\n\n /// @notice Set this as asset address for BNB. This is the underlying address for vBNB\n address public constant BNB_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n /// @notice Manually set an override price, useful under extenuating conditions such as price feed failure\n mapping(address => uint256) public prices;\n\n /// @notice Token config by assets\n mapping(address => TokenConfig) public tokenConfigs;\n\n /// @notice Emit when a price is manually set\n event PricePosted(address indexed asset, uint256 previousPriceMantissa, uint256 newPriceMantissa);\n\n /// @notice Emit when a token config is added\n event TokenConfigAdded(address indexed asset, address feed, uint256 maxStalePeriod);\n\n modifier notNullAddress(address someone) {\n if (someone == address(0)) revert(\"can't be zero address\");\n _;\n }\n\n /// @notice Constructor for the implementation contract.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Manually set the price of a given asset\n * @param asset Asset address\n * @param price Asset price in 18 decimals\n * @custom:access Only Governance\n * @custom:event Emits PricePosted event on succesfully setup of asset price\n */\n function setDirectPrice(address asset, uint256 price) external notNullAddress(asset) {\n _checkAccessAllowed(\"setDirectPrice(address,uint256)\");\n\n uint256 previousPriceMantissa = prices[asset];\n prices[asset] = price;\n emit PricePosted(asset, previousPriceMantissa, price);\n }\n\n /**\n * @notice Add multiple token configs at the same time\n * @param tokenConfigs_ config array\n * @custom:access Only Governance\n * @custom:error Zero length error thrown, if length of the array in parameter is 0\n */\n function setTokenConfigs(TokenConfig[] memory tokenConfigs_) external {\n if (tokenConfigs_.length == 0) revert(\"length can't be 0\");\n uint256 numTokenConfigs = tokenConfigs_.length;\n for (uint256 i; i < numTokenConfigs; ) {\n setTokenConfig(tokenConfigs_[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Initializes the owner of the contract\n * @param accessControlManager_ Address of the access control manager contract\n */\n function initialize(address accessControlManager_) external initializer {\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Add single token config. asset & feed cannot be null addresses and maxStalePeriod must be positive\n * @param tokenConfig Token config struct\n * @custom:access Only Governance\n * @custom:error NotNullAddress error is thrown if asset address is null\n * @custom:error NotNullAddress error is thrown if token feed address is null\n * @custom:error Range error is thrown if maxStale period of token is not greater than zero\n * @custom:event Emits TokenConfigAdded event on succesfully setting of the token config\n */\n function setTokenConfig(\n TokenConfig memory tokenConfig\n ) public notNullAddress(tokenConfig.asset) notNullAddress(tokenConfig.feed) {\n _checkAccessAllowed(\"setTokenConfig(TokenConfig)\");\n\n if (tokenConfig.maxStalePeriod == 0) revert(\"stale period can't be zero\");\n tokenConfigs[tokenConfig.asset] = tokenConfig;\n emit TokenConfigAdded(tokenConfig.asset, tokenConfig.feed, tokenConfig.maxStalePeriod);\n }\n\n /**\n * @notice Gets the price of a asset from the chainlink oracle\n * @param asset Address of the asset\n * @return Price in USD from Chainlink or a manually set price for the asset\n */\n function getPrice(address asset) public view returns (uint256) {\n uint256 decimals;\n\n if (asset == BNB_ADDR) {\n decimals = 18;\n } else {\n IERC20Metadata token = IERC20Metadata(asset);\n decimals = token.decimals();\n }\n\n return _getPriceInternal(asset, decimals);\n }\n\n /**\n * @notice Gets the Chainlink price for a given asset\n * @param asset address of the asset\n * @param decimals decimals of the asset\n * @return price Asset price in USD or a manually set price of the asset\n */\n function _getPriceInternal(address asset, uint256 decimals) internal view returns (uint256 price) {\n uint256 tokenPrice = prices[asset];\n if (tokenPrice != 0) {\n price = tokenPrice;\n } else {\n price = _getChainlinkPrice(asset);\n }\n\n uint256 decimalDelta = 18 - decimals;\n return price * (10 ** decimalDelta);\n }\n\n /**\n * @notice Get the Chainlink price for an asset, revert if token config doesn't exist\n * @dev The precision of the price feed is used to ensure the returned price has 18 decimals of precision\n * @param asset Address of the asset\n * @return price Price in USD, with 18 decimals of precision\n * @custom:error NotNullAddress error is thrown if the asset address is null\n * @custom:error Price error is thrown if the Chainlink price of asset is not greater than zero\n * @custom:error Timing error is thrown if current timestamp is less than the last updatedAt timestamp\n * @custom:error Timing error is thrown if time difference between current time and last updated time\n * is greater than maxStalePeriod\n */\n function _getChainlinkPrice(\n address asset\n ) private view notNullAddress(tokenConfigs[asset].asset) returns (uint256) {\n TokenConfig memory tokenConfig = tokenConfigs[asset];\n AggregatorV3Interface feed = AggregatorV3Interface(tokenConfig.feed);\n\n // note: maxStalePeriod cannot be 0\n uint256 maxStalePeriod = tokenConfig.maxStalePeriod;\n\n // Chainlink USD-denominated feeds store answers at 8 decimals, mostly\n uint256 decimalDelta = 18 - feed.decimals();\n\n (, int256 answer, , uint256 updatedAt, ) = feed.latestRoundData();\n if (answer <= 0) revert(\"chainlink price must be positive\");\n if (block.timestamp < updatedAt) revert(\"updatedAt exceeds block time\");\n\n uint256 deltaTime;\n unchecked {\n deltaTime = block.timestamp - updatedAt;\n }\n\n if (deltaTime > maxStalePeriod) revert(\"chainlink price expired\");\n\n return uint256(answer) * (10 ** decimalDelta);\n }\n}\n" + }, + "contracts/Comptroller.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { ComptrollerInterface } from \"./ComptrollerInterface.sol\";\nimport { ComptrollerStorage } from \"./ComptrollerStorage.sol\";\nimport { ExponentialNoError } from \"./ExponentialNoError.sol\";\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\nimport { MaxLoopsLimitHelper } from \"./MaxLoopsLimitHelper.sol\";\nimport { ensureNonzeroAddress } from \"./lib/validators.sol\";\n\n/**\n * @title Comptroller\n * @author Venus\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market’s corresponding liquidation threshold,\n * the borrow is eligible for liquidation.\n *\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\n * the `minLiquidatableCollateral` for the `Comptroller`:\n *\n * - `healAccount()`: This function is called to seize all of a given user’s collateral, requiring the `msg.sender` repay a certain percentage\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\n * verifying that the repay amount does not exceed the close factor.\n */\ncontract Comptroller is\n Ownable2StepUpgradeable,\n AccessControlledV8,\n ComptrollerStorage,\n ComptrollerInterface,\n ExponentialNoError,\n MaxLoopsLimitHelper\n{\n // PoolRegistry, immutable to save on gas\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n address public immutable poolRegistry;\n\n /// @notice Emitted when an account enters a market\n event MarketEntered(VToken indexed vToken, address indexed account);\n\n /// @notice Emitted when an account exits a market\n event MarketExited(VToken indexed vToken, address indexed account);\n\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\n\n /// @notice Emitted when liquidation threshold is changed by admin\n event NewLiquidationThreshold(\n VToken vToken,\n uint256 oldLiquidationThresholdMantissa,\n uint256 newLiquidationThresholdMantissa\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\n\n /// @notice Emitted when an action is paused on a market\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\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 the collateral threshold (in USD) for non-batch liquidations is changed\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\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 a rewards distributor is added\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\n\n /// @notice Emitted when a market is supported\n event MarketSupported(VToken vToken);\n\n /// @notice Thrown when collateral factor exceeds the upper bound\n error InvalidCollateralFactor();\n\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\n error InvalidLiquidationThreshold();\n\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\n error UnexpectedSender(address expectedSender, address actualSender);\n\n /// @notice Thrown when the oracle returns an invalid price for some asset\n error PriceError(address vToken);\n\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\n error SnapshotError(address vToken, address user);\n\n /// @notice Thrown when the market is not listed\n error MarketNotListed(address market);\n\n /// @notice Thrown when a market has an unexpected comptroller\n error ComptrollerMismatch();\n\n /// @notice Thrown when user is not member of market\n error MarketNotCollateral(address vToken, address user);\n\n /**\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\n * or healAccount) are available.\n */\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\n\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\n error InsufficientLiquidity();\n\n /// @notice Thrown when trying to liquidate a healthy account\n error InsufficientShortfall();\n\n /// @notice Thrown when trying to repay more than allowed by close factor\n error TooMuchRepay();\n\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\n error NonzeroBorrowBalance();\n\n /// @notice Thrown when trying to perform an action that is paused\n error ActionPaused(address market, Action action);\n\n /// @notice Thrown when trying to add a market that is already listed\n error MarketAlreadyListed(address market);\n\n /// @notice Thrown if the supply cap is exceeded\n error SupplyCapExceeded(address market, uint256 cap);\n\n /// @notice Thrown if the borrow cap is exceeded\n error BorrowCapExceeded(address market, uint256 cap);\n\n /// @param poolRegistry_ Pool registry address\n /// @custom:oz-upgrades-unsafe-allow constructor\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n constructor(address poolRegistry_) {\n ensureNonzeroAddress(poolRegistry_);\n\n poolRegistry = poolRegistry_;\n _disableInitializers();\n }\n\n /**\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\n * @param accessControlManager Access control manager contract address\n */\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager);\n\n _setMaxLoopsLimit(loopLimit);\n }\n\n /**\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\n * @param vTokens The list of addresses of the vToken markets to be enabled\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\n * @custom:event MarketEntered is emitted for each market on success\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\n * @custom:access Not restricted\n */\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\n uint256 len = vTokens.length;\n\n uint256[] memory results = new uint256[](len);\n for (uint256 i; i < len; ++i) {\n VToken vToken = VToken(vTokens[i]);\n\n _addToMarket(vToken, msg.sender);\n results[i] = NO_ERROR;\n }\n\n return results;\n }\n\n /**\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event MarketExited is emitted on success\n * @custom:error ActionPaused error is thrown if exiting the market is paused\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function exitMarket(address vTokenAddress) external override returns (uint256) {\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\n VToken vToken = VToken(vTokenAddress);\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\n\n /* Fail if the sender has a borrow balance */\n if (amountOwed != 0) {\n revert NonzeroBorrowBalance();\n }\n\n /* Fail if the sender is not permitted to redeem all of their tokens */\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\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 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 // load into memory for faster iteration\n VToken[] memory userAssetList = accountAssets[msg.sender];\n uint256 len = userAssetList.length;\n\n uint256 assetIndex = len;\n for (uint256 i; i < len; ++i) {\n if (userAssetList[i] == vToken) {\n assetIndex = i;\n break;\n }\n }\n\n // We *must* have found the asset in the list or our redundant data structure is broken\n assert(assetIndex < len);\n\n // copy last item in list to location of item to be removed, reduce length by 1\n VToken[] storage storedList = accountAssets[msg.sender];\n storedList[assetIndex] = storedList[storedList.length - 1];\n storedList.pop();\n\n emit MarketExited(vToken, msg.sender);\n\n return NO_ERROR;\n }\n\n /*** Policy Hooks ***/\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\n * @custom:access Not restricted\n */\n function preMintHook(\n address vToken,\n address minter,\n uint256 mintAmount\n ) external override {\n _checkActionPauseState(vToken, Action.MINT);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n uint256 supplyCap = supplyCaps[vToken];\n // Skipping the cap check for uncapped coins to save some gas\n if (supplyCap != type(uint256).max) {\n uint256 vTokenSupply = VToken(vToken).totalSupply();\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\n if (nextTotalSupply > supplyCap) {\n revert SupplyCapExceeded(vToken, supplyCap);\n }\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function preRedeemHook(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) external override {\n _checkActionPauseState(vToken, Action.REDEEM);\n\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\n */\n /// disable-eslint\n function preBorrowHook(\n address vToken,\n address borrower,\n uint256 borrowAmount\n ) external override {\n _checkActionPauseState(vToken, Action.BORROW);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n if (!markets[vToken].accountMembership[borrower]) {\n // only vTokens may call borrowAllowed if borrower not in market\n _checkSenderIs(vToken);\n\n // attempt to add borrower to the market or revert\n _addToMarket(VToken(msg.sender), borrower);\n }\n\n // Update the prices of tokens\n updatePrices(borrower);\n\n if (oracle.getUnderlyingPrice(vToken) == 0) {\n revert PriceError(address(vToken));\n }\n\n uint256 borrowCap = borrowCaps[vToken];\n // Skipping the cap check for uncapped coins to save some gas\n if (borrowCap != type(uint256).max) {\n uint256 totalBorrows = VToken(vToken).totalBorrows();\n uint256 badDebt = VToken(vToken).badDebt();\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\n if (nextTotalBorrows > borrowCap) {\n revert BorrowCapExceeded(vToken, borrowCap);\n }\n }\n\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n borrower,\n VToken(vToken),\n 0,\n borrowAmount,\n _getCollateralFactor\n );\n\n if (snapshot.shortfall > 0) {\n revert InsufficientLiquidity();\n }\n\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\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 borrower The account which would borrowed the asset\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:access Not restricted\n */\n function preRepayHook(address vToken, address borrower) external override {\n _checkActionPauseState(vToken, Action.REPAY);\n\n oracle.updatePrice(vToken);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\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 borrower The address of the borrower\n * @param repayAmount The amount of underlying being repaid\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n */\n function preLiquidateHook(\n address vTokenBorrowed,\n address vTokenCollateral,\n address borrower,\n uint256 repayAmount,\n bool skipLiquidityCheck\n ) external override {\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\n // If we want to pause liquidating to vTokenCollateral, we should pause\n // Action.SEIZE on it\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\n\n // Update the prices of tokens\n updatePrices(borrower);\n\n if (!markets[vTokenBorrowed].isListed) {\n revert MarketNotListed(address(vTokenBorrowed));\n }\n if (!markets[vTokenCollateral].isListed) {\n revert MarketNotListed(address(vTokenCollateral));\n }\n\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\n\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\n if (repayAmount > borrowBalance) {\n revert TooMuchRepay();\n }\n return;\n }\n\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\n /* The liquidator should use either liquidateAccount or healAccount */\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n /* The liquidator may not repay more than what is allowed by the closeFactor */\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\n if (repayAmount > maxClose) {\n revert TooMuchRepay();\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\n * @custom:access Not restricted\n */\n function preSeizeHook(\n address vTokenCollateral,\n address seizerContract,\n address liquidator,\n address borrower\n ) external override {\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\n // If we want to pause liquidating vTokenBorrowed, we should pause\n // Action.LIQUIDATE on it\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\n\n Market storage market = markets[vTokenCollateral];\n\n if (!market.isListed) {\n revert MarketNotListed(vTokenCollateral);\n }\n\n if (seizerContract == address(this)) {\n // If Comptroller is the seizer, just check if collateral's comptroller\n // is equal to the current address\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\n revert ComptrollerMismatch();\n }\n } else {\n // If the seizer is not the Comptroller, check that the seizer is a\n // listed market, and that the markets' comptrollers match\n if (!markets[seizerContract].isListed) {\n revert MarketNotListed(seizerContract);\n }\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\n revert ComptrollerMismatch();\n }\n }\n\n if (!market.accountMembership[borrower]) {\n revert MarketNotCollateral(vTokenCollateral, borrower);\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function preTransferHook(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external override {\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 _checkRedeemAllowed(vToken, src, transferTokens);\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\n }\n }\n\n /*** Pool-level operations ***/\n\n /**\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\n * borrows, and treats the rest of the debt as bad debt (for each market).\n * The sender has to repay a certain percentage of the debt, computed as\n * collateral / (borrows * liquidationIncentive).\n * @param user account to heal\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function healAccount(address user) external {\n VToken[] memory userAssets = accountAssets[user];\n uint256 userAssetsCount = userAssets.length;\n\n address liquidator = msg.sender;\n {\n ResilientOracleInterface oracle_ = oracle;\n // We need all user's markets to be fresh for the computations to be correct\n for (uint256 i; i < userAssetsCount; ++i) {\n userAssets[i].accrueInterest();\n oracle_.updatePrice(address(userAssets[i]));\n }\n }\n\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n // percentage = collateral / (borrows * liquidation incentive)\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\n Exp memory scaledBorrows = mul_(\n Exp({ mantissa: snapshot.borrows }),\n Exp({ mantissa: liquidationIncentiveMantissa })\n );\n\n Exp memory percentage = div_(collateral, scaledBorrows);\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\n }\n\n for (uint256 i; i < userAssetsCount; ++i) {\n VToken market = userAssets[i];\n\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\n\n // Seize the entire collateral\n if (tokens != 0) {\n market.seize(liquidator, user, tokens);\n }\n // Repay a certain percentage of the borrow, forgive the rest\n if (borrowBalance != 0) {\n market.healBorrow(liquidator, user, repaymentAmount);\n }\n }\n }\n\n /**\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\n * below the threshold, and the account is insolvent, use healAccount.\n * @param borrower the borrower address\n * @param orders an array of liquidation orders\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\n // We will accrue interest and update the oracle prices later during the liquidation\n\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\n // You should use the regular vToken.liquidateBorrow(...) call\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n uint256 collateralToSeize = mul_ScalarTruncate(\n Exp({ mantissa: liquidationIncentiveMantissa }),\n snapshot.borrows\n );\n if (collateralToSeize >= snapshot.totalCollateral) {\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\n // and record bad debt.\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n uint256 ordersCount = orders.length;\n\n _ensureMaxLoops(ordersCount / 2);\n\n for (uint256 i; i < ordersCount; ++i) {\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\n }\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\n revert MarketNotListed(address(orders[i].vTokenCollateral));\n }\n\n LiquidationOrder calldata order = orders[i];\n order.vTokenBorrowed.forceLiquidateBorrow(\n msg.sender,\n borrower,\n order.repayAmount,\n order.vTokenCollateral,\n true\n );\n }\n\n VToken[] memory borrowMarkets = accountAssets[borrower];\n uint256 marketsCount = borrowMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\n require(borrowBalance == 0, \"Nonzero borrow balance after liquidation\");\n }\n }\n\n /**\n * @notice Sets the closeFactor to use when liquidating borrows\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\n * @custom:event Emits NewCloseFactor on success\n * @custom:access Controlled by AccessControlManager\n */\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\n _checkAccessAllowed(\"setCloseFactor(uint256)\");\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \"Close factor greater than maximum close factor\");\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \"Close factor smaller than minimum close factor\");\n\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\n closeFactorMantissa = newCloseFactorMantissa;\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\n }\n\n /**\n * @notice Sets the collateralFactor for a market\n * @dev This function is restricted by the AccessControlManager\n * @param vToken The market to set the factor on\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\n * and NewLiquidationThreshold when liquidation threshold is updated\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\n * @custom:access Controlled by AccessControlManager\n */\n function setCollateralFactor(\n VToken vToken,\n uint256 newCollateralFactorMantissa,\n uint256 newLiquidationThresholdMantissa\n ) external {\n _checkAccessAllowed(\"setCollateralFactor(address,uint256,uint256)\");\n\n // Verify market is listed\n Market storage market = markets[address(vToken)];\n if (!market.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n // Check collateral factor <= 0.9\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\n revert InvalidCollateralFactor();\n }\n\n // Ensure that liquidation threshold <= 1\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\n revert InvalidLiquidationThreshold();\n }\n\n // Ensure that liquidation threshold >= CF\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\n revert InvalidLiquidationThreshold();\n }\n\n // If collateral factor != 0, fail if price == 0\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\n revert PriceError(address(vToken));\n }\n\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\n market.collateralFactorMantissa = newCollateralFactorMantissa;\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\n }\n\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\n }\n }\n\n /**\n * @notice Sets liquidationIncentive\n * @dev This function is restricted by the AccessControlManager\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\n * @custom:event Emits NewLiquidationIncentive on success\n * @custom:access Controlled by AccessControlManager\n */\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \"liquidation incentive should be greater than 1e18\");\n\n _checkAccessAllowed(\"setLiquidationIncentive(uint256)\");\n\n // Save current value for use in log\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\n\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\n /**\n * @notice Add the market to the markets mapping and set it as listed\n * @dev Only callable by the PoolRegistry\n * @param vToken The address of the market (token) to list\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\n * @custom:access Only PoolRegistry\n */\n function supportMarket(VToken vToken) external {\n _checkSenderIs(poolRegistry);\n\n if (markets[address(vToken)].isListed) {\n revert MarketAlreadyListed(address(vToken));\n }\n\n require(vToken.isVToken(), \"Comptroller: Invalid vToken\"); // Sanity check to make sure its really a VToken\n\n Market storage newMarket = markets[address(vToken)];\n newMarket.isListed = true;\n newMarket.collateralFactorMantissa = 0;\n newMarket.liquidationThresholdMantissa = 0;\n\n _addMarket(address(vToken));\n\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n rewardsDistributors[i].initializeMarket(address(vToken));\n }\n\n emit MarketSupported(vToken);\n }\n\n /**\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\n * @dev This function is restricted by the AccessControlManager\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\n until the total borrows amount goes below the new borrow cap\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 type(uint256).max corresponds to unlimited borrowing.\n * @custom:access Controlled by AccessControlManager\n */\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\n _checkAccessAllowed(\"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 _ensureMaxLoops(numMarkets);\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 markets. Supply that brings total Supply to or above supply cap will revert.\n * @dev This function is restricted by the AccessControlManager\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\n until the total supplies amount goes below the new supply cap\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 type(uint256).max corresponds to unlimited supply.\n * @custom:access Controlled by AccessControlManager\n */\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\n _checkAccessAllowed(\"setMarketSupplyCaps(address[],uint256[])\");\n uint256 vTokensCount = vTokens.length;\n\n require(vTokensCount != 0, \"invalid number of markets\");\n require(vTokensCount == newSupplyCaps.length, \"invalid number of markets\");\n\n _ensureMaxLoops(vTokensCount);\n\n for (uint256 i; i < vTokensCount; ++i) {\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\n }\n }\n\n /**\n * @notice Pause/unpause specified actions\n * @dev This function is restricted by the AccessControlManager\n * @param marketsList Markets to pause/unpause the actions on\n * @param actionsList List of action ids to pause/unpause\n * @param paused The new paused state (true=paused, false=unpaused)\n * @custom:access Controlled by AccessControlManager\n */\n function setActionsPaused(\n VToken[] calldata marketsList,\n Action[] calldata actionsList,\n bool paused\n ) external {\n _checkAccessAllowed(\"setActionsPaused(address[],uint256[],bool)\");\n\n uint256 marketsCount = marketsList.length;\n uint256 actionsCount = actionsList.length;\n\n _ensureMaxLoops(marketsCount * actionsCount);\n\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\n }\n }\n }\n\n /**\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\n * operations like liquidateAccount or healAccount.\n * @dev This function is restricted by the AccessControlManager\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\n * @custom:access Controlled by AccessControlManager\n */\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\n _checkAccessAllowed(\"setMinLiquidatableCollateral(uint256)\");\n\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\n minLiquidatableCollateral = newMinLiquidatableCollateral;\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\n }\n\n /**\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\n * @dev Only callable by the admin\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\n * @custom:access Only Governance\n * @custom:event Emits NewRewardsDistributor with distributor address\n */\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \"already exists\");\n\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\n _ensureMaxLoops(rewardsDistributorsLen + 1);\n\n rewardsDistributors.push(_rewardsDistributor);\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\n\n uint256 marketsCount = allMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\n }\n\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\n }\n\n /**\n * @notice Sets a new price oracle for the Comptroller\n * @dev Only callable by the admin\n * @param newOracle Address of the new price oracle to set\n * @custom:event Emits NewPriceOracle on success\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\n */\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\n ensureNonzeroAddress(address(newOracle));\n\n ResilientOracleInterface oldOracle = oracle;\n oracle = newOracle;\n emit NewPriceOracle(oldOracle, newOracle);\n }\n\n /**\n * @notice Set the for loop iteration limit to avoid DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\n * @param account The account get liquidity for\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\n * @return shortfall Account shortfall below liquidation threshold requirements\n */\n function getAccountLiquidity(address account)\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\n }\n\n /**\n * @notice Determine the current account liquidity with respect to collateral requirements\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\n * @param account The account get liquidity for\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Account liquidity in excess of collateral requirements,\n * @return shortfall Account shortfall below collateral requirements\n */\n function getBorrowingPower(address account)\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\n }\n\n /**\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\n * @return shortfall Hypothetical account shortfall below collateral requirements\n */\n function getHypotheticalAccountLiquidity(\n address account,\n address vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n )\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n account,\n VToken(vTokenModify),\n redeemTokens,\n borrowAmount,\n _getCollateralFactor\n );\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\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 markets The list of market addresses\n */\n function getAllMarkets() external view override returns (VToken[] memory) {\n return allMarkets;\n }\n\n /**\n * @notice Check if a market is marked as listed (active)\n * @param vToken vToken Address for the market to check\n * @return listed True if listed otherwise false\n */\n function isMarketListed(VToken vToken) external view returns (bool) {\n return markets[address(vToken)].isListed;\n }\n\n /*** Assets You Are In ***/\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 list with the assets the account has entered\n */\n function getAssetsIn(address account) external view returns (VToken[] memory) {\n VToken[] memory assetsIn = accountAssets[account];\n\n return assetsIn;\n }\n\n /**\n * @notice Returns whether the given account is entered in a given market\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\n * @custom:error PriceError if the oracle returns an invalid price\n */\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\n /* Read oracle prices for borrowed and collateral markets */\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\n uint256 seizeTokens;\n Exp memory numerator;\n Exp memory denominator;\n Exp memory ratio;\n\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\n ratio = div_(numerator, denominator);\n\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\n\n return (NO_ERROR, seizeTokens);\n }\n\n /**\n * @notice Returns reward speed given a vToken\n * @param vToken The vToken to get the reward speeds for\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\n */\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n address rewardToken = address(rewardsDistributor.rewardToken());\n rewardSpeeds[i] = RewardSpeeds({\n rewardToken: rewardToken,\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\n });\n }\n return rewardSpeeds;\n }\n\n /**\n * @notice Return all reward distributors for this pool\n * @return Array of RewardDistributor addresses\n */\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\n return rewardsDistributors;\n }\n\n /**\n * @notice A marker method that returns true for a valid Comptroller contract\n * @return Always true\n */\n function isComptroller() external pure override returns (bool) {\n return true;\n }\n\n /**\n * @notice Update the prices of all the tokens associated with the provided account\n * @param account Address of the account to get associated tokens with\n */\n function updatePrices(address account) public {\n VToken[] memory vTokens = accountAssets[account];\n uint256 vTokensCount = vTokens.length;\n\n ResilientOracleInterface oracle_ = oracle;\n\n for (uint256 i; i < vTokensCount; ++i) {\n oracle_.updatePrice(address(vTokens[i]));\n }\n }\n\n /**\n * @notice Checks if a certain action is paused on a market\n * @param market vToken address\n * @param action Action to check\n * @return paused True if the action is paused otherwise false\n */\n function actionPaused(address market, Action action) public view returns (bool) {\n return _actionPaused[market][action];\n }\n\n /**\n * @notice Check if a vToken market has been deprecated\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\n * @param vToken The market to check if deprecated\n * @return deprecated True if the given vToken market has been deprecated\n */\n function isDeprecated(VToken vToken) public view returns (bool) {\n return\n markets[address(vToken)].collateralFactorMantissa == 0 &&\n actionPaused(address(vToken), Action.BORROW) &&\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\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 */\n function _addToMarket(VToken vToken, address borrower) internal {\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\n Market storage marketToJoin = markets[address(vToken)];\n\n if (!marketToJoin.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n if (marketToJoin.accountMembership[borrower]) {\n // already joined\n return;\n }\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\n /**\n * @notice Internal function to validate that a market hasn't already been added\n * and if it hasn't adds it\n * @param vToken The market to support\n */\n function _addMarket(address vToken) internal {\n uint256 marketsCount = allMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n if (allMarkets[i] == VToken(vToken)) {\n revert MarketAlreadyListed(vToken);\n }\n }\n allMarkets.push(VToken(vToken));\n marketsCount = allMarkets.length;\n _ensureMaxLoops(marketsCount);\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 _setActionPaused(\n address market,\n Action action,\n bool paused\n ) internal {\n require(markets[market].isListed, \"cannot pause a market that is not listed\");\n _actionPaused[market][action] = paused;\n emit ActionPausedMarket(VToken(market), action, paused);\n }\n\n /**\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\n * @param vToken Address of the vTokens to redeem\n * @param redeemer Account redeeming the tokens\n * @param redeemTokens The number of tokens to redeem\n */\n function _checkRedeemAllowed(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) internal {\n Market storage market = markets[vToken];\n\n if (!market.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\n if (!market.accountMembership[redeemer]) {\n return;\n }\n\n // Update the prices of tokens\n updatePrices(redeemer);\n\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n redeemer,\n VToken(vToken),\n redeemTokens,\n 0,\n _getCollateralFactor\n );\n if (snapshot.shortfall > 0) {\n revert InsufficientLiquidity();\n }\n }\n\n /**\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\n * @param account The account to get the snapshot for\n * @param weight The function to compute the weight of the collateral – either collateral factor or\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\n * without calculating accumulated interest.\n * @return snapshot Account liquidity snapshot\n */\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\n internal\n view\n returns (AccountLiquiditySnapshot memory snapshot)\n {\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\n }\n\n /**\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral – either collateral factor or\n liquidation threshold. Accepts the address of the VToken and returns the weight\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\n * without calculating accumulated interest.\n * @return snapshot Account liquidity snapshot\n */\n function _getHypotheticalLiquiditySnapshot(\n address account,\n VToken vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount,\n function(VToken) internal view returns (Exp memory) weight\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\n // For each asset the account is in\n VToken[] memory assets = accountAssets[account];\n uint256 assetsCount = assets.length;\n\n for (uint256 i; i < assetsCount; ++i) {\n VToken asset = assets[i];\n\n // Read the balances and exchange rate from the vToken\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\n asset,\n account\n );\n\n // Get the normalized price of the asset\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\n\n // Pre-compute conversion factors from vTokens -> usd\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\n\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\n weightedVTokenPrice,\n vTokenBalance,\n snapshot.weightedCollateral\n );\n\n // totalCollateral += vTokenPrice * vTokenBalance\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\n\n // borrows += oraclePrice * borrowBalance\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\n\n // Calculate effects of interacting with vTokenModify\n if (asset == vTokenModify) {\n // redeem effect\n // effects += tokensToDenom * redeemTokens\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\n\n // borrow effect\n // effects += oraclePrice * borrowAmount\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\n }\n }\n\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\n // These are safe, as the underflow condition is checked first\n unchecked {\n if (snapshot.weightedCollateral > borrowPlusEffects) {\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\n snapshot.shortfall = 0;\n } else {\n snapshot.liquidity = 0;\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\n }\n }\n\n return snapshot;\n }\n\n /**\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\n * @param asset Address for asset to query price\n * @return Underlying price\n */\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\n if (oraclePriceMantissa == 0) {\n revert PriceError(address(asset));\n }\n return oraclePriceMantissa;\n }\n\n /**\n * @dev Return collateral factor for a market\n * @param asset Address for asset\n * @return Collateral factor as exponential\n */\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\n }\n\n /**\n * @dev Retrieves liquidation threshold for a market as an exponential\n * @param asset Address for asset to liquidation threshold\n * @return Liquidation threshold as exponential\n */\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\n }\n\n /**\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\n * @param vToken Market to query\n * @param user Account address\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\n * @return borrowBalance Borrowed amount, including the interest\n * @return exchangeRateMantissa Stored exchange rate\n */\n function _safeGetAccountSnapshot(VToken vToken, address user)\n internal\n view\n returns (\n uint256 vTokenBalance,\n uint256 borrowBalance,\n uint256 exchangeRateMantissa\n )\n {\n uint256 err;\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\n if (err != 0) {\n revert SnapshotError(address(vToken), user);\n }\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\n }\n\n /// @notice Reverts if the call is not from expectedSender\n /// @param expectedSender Expected transaction sender\n function _checkSenderIs(address expectedSender) internal view {\n if (msg.sender != expectedSender) {\n revert UnexpectedSender(expectedSender, msg.sender);\n }\n }\n\n /// @notice Reverts if a certain action is paused on a market\n /// @param market Market to check\n /// @param action Action to check\n function _checkActionPauseState(address market, Action action) private view {\n if (actionPaused(market, action)) {\n revert ActionPaused(market, action);\n }\n }\n}\n" + }, + "contracts/ComptrollerInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\n\n/**\n * @title ComptrollerInterface\n * @author Venus\n * @notice Interface implemented by the `Comptroller` contract.\n */\ninterface ComptrollerInterface {\n /*** Assets You Are In ***/\n\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\n\n function exitMarket(address vToken) external returns (uint256);\n\n /*** Policy Hooks ***/\n\n function preMintHook(\n address vToken,\n address minter,\n uint256 mintAmount\n ) external;\n\n function preRedeemHook(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) external;\n\n function preBorrowHook(\n address vToken,\n address borrower,\n uint256 borrowAmount\n ) external;\n\n function preRepayHook(address vToken, address borrower) external;\n\n function preLiquidateHook(\n address vTokenBorrowed,\n address vTokenCollateral,\n address borrower,\n uint256 repayAmount,\n bool skipLiquidityCheck\n ) external;\n\n function preSeizeHook(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower\n ) external;\n\n function preTransferHook(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external;\n\n function isComptroller() external view returns (bool);\n\n /*** Liquidity/Liquidation Calculations ***/\n\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 repayAmount\n ) external view returns (uint256, uint256);\n\n function getAllMarkets() external view returns (VToken[] memory);\n}\n\n/**\n * @title ComptrollerViewInterface\n * @author Venus\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\n */\ninterface ComptrollerViewInterface {\n function markets(address) external view returns (bool, uint256);\n\n function oracle() external view returns (ResilientOracleInterface);\n\n function getAssetsIn(address) external view returns (VToken[] memory);\n\n function closeFactorMantissa() external view returns (uint256);\n\n function liquidationIncentiveMantissa() external view returns (uint256);\n\n function minLiquidatableCollateral() external view returns (uint256);\n\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\n\n function getAllMarkets() external view returns (VToken[] memory);\n\n function borrowCaps(address) external view returns (uint256);\n\n function supplyCaps(address) external view returns (uint256);\n}\n" + }, + "contracts/ComptrollerStorage.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\n\n/**\n * @title ComptrollerStorage\n * @author Venus\n * @notice Storage layout for the `Comptroller` contract.\n */\ncontract ComptrollerStorage {\n struct LiquidationOrder {\n VToken vTokenCollateral;\n VToken vTokenBorrowed;\n uint256 repayAmount;\n }\n\n struct AccountLiquiditySnapshot {\n uint256 totalCollateral;\n uint256 weightedCollateral;\n uint256 borrows;\n uint256 effects;\n uint256 liquidity;\n uint256 shortfall;\n }\n\n struct RewardSpeeds {\n address rewardToken;\n uint256 supplySpeed;\n uint256 borrowSpeed;\n }\n\n struct Market {\n // Whether or not this market is listed\n bool isListed;\n // 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 uint256 collateralFactorMantissa;\n // Multiplier representing the collateralization after which the borrow is eligible\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\n // value. Must be between 0 and collateral factor, stored as a mantissa.\n uint256 liquidationThresholdMantissa;\n // Per-market mapping of \"accounts in this asset\"\n mapping(address => bool) accountMembership;\n }\n\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 /**\n * @notice Oracle which gives the price of any given asset\n */\n ResilientOracleInterface 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 Per-account mapping of \"assets you are in\"\n */\n mapping(address => VToken[]) public accountAssets;\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 /// @notice A list of all markets\n VToken[] public allMarkets;\n\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\n mapping(address => uint256) public borrowCaps;\n\n /// @notice Minimal collateral required for regular (non-batch) liquidations\n uint256 public minLiquidatableCollateral;\n\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\n mapping(address => uint256) public supplyCaps;\n\n /// @notice True if a certain action is paused on a certain market\n mapping(address => mapping(Action => bool)) internal _actionPaused;\n\n // List of Reward Distributors added\n RewardsDistributor[] internal rewardsDistributors;\n\n // Used to check if rewards distributor is added\n mapping(address => bool) internal rewardsDistributorExists;\n\n uint256 internal constant NO_ERROR = 0;\n\n // closeFactorMantissa must be strictly greater than this value\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\n\n // closeFactorMantissa must not exceed this value\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\n\n // No collateralFactorMantissa may exceed this value\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\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[50] private __gap;\n}\n" + }, + "contracts/ErrorReporter.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title TokenErrorReporter\n * @author Venus\n * @notice Errors that can be thrown by the `VToken` contract.\n */\ncontract TokenErrorReporter {\n uint256 public constant NO_ERROR = 0; // support legacy return codes\n\n error TransferNotAllowed();\n\n error MintFreshnessCheck();\n\n error RedeemFreshnessCheck();\n error RedeemTransferOutNotPossible();\n\n error BorrowFreshnessCheck();\n error BorrowCashNotAvailable();\n\n error RepayBorrowFreshnessCheck();\n\n error HealBorrowUnauthorized();\n error ForceLiquidateBorrowUnauthorized();\n\n error LiquidateFreshnessCheck();\n error LiquidateCollateralFreshnessCheck();\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\n error LiquidateLiquidatorIsBorrower();\n error LiquidateCloseAmountIsZero();\n error LiquidateCloseAmountIsUintMax();\n\n error LiquidateSeizeLiquidatorIsBorrower();\n\n error ProtocolSeizeShareTooBig();\n\n error SetReserveFactorFreshCheck();\n error SetReserveFactorBoundsCheck();\n\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\n\n error ReduceReservesFreshCheck();\n error ReduceReservesCashNotAvailable();\n error ReduceReservesCashValidation();\n\n error SetInterestRateModelFreshCheck();\n}\n" + }, + "contracts/ExponentialNoError.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \"./lib/constants.sol\";\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 struct Exp {\n uint256 mantissa;\n }\n\n struct Double {\n uint256 mantissa;\n }\n\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\n uint256 internal constant DOUBLE_SCALE = 1e36;\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\n\n /**\n * @dev Truncates the given exp to a whole number value.\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\n */\n function truncate(Exp memory exp) internal pure returns (uint256) {\n // Note: We are not using careful math here as we're performing a division that cannot fail\n return exp.mantissa / EXP_SCALE;\n }\n\n /**\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\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 // solhint-disable-next-line func-name-mixedcase\n function mul_ScalarTruncateAddUInt(\n Exp memory a,\n uint256 scalar,\n uint256 addend\n ) internal pure returns (uint256) {\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\n require(n <= type(uint224).max, errorMessage);\n return uint224(n);\n }\n\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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_(uint256 a, uint256 b) internal pure returns (uint256) {\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) / EXP_SCALE });\n }\n\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\n return mul_(a, b.mantissa) / EXP_SCALE;\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) / DOUBLE_SCALE });\n }\n\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\n }\n\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\n }\n\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\n }\n\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\n }\n\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\n }\n}\n" + }, + "contracts/InterestRateModel.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title Compound's InterestRateModel Interface\n * @author Compound\n */\nabstract contract InterestRateModel {\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 amount of reserves the market has\n * @param badDebt The amount of badDebt in the market\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\n */\n function getBorrowRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) external view virtual returns (uint256);\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 amount of reserves the market has\n * @param reserveFactorMantissa The current reserve factor the market has\n * @param badDebt The amount of badDebt in the market\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\n */\n function getSupplyRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 reserveFactorMantissa,\n uint256 badDebt\n ) external view virtual returns (uint256);\n\n /**\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\n * @return Always true\n */\n function isInterestRateModel() external pure virtual returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/IPancakeswapV2Router.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface IPancakeswapV2Router {\n function swapExactTokensForTokens(\n uint256 amountIn,\n uint256 amountOutMin,\n address[] calldata path,\n address to,\n uint256 deadline\n ) external returns (uint256[] memory amounts);\n}\n" + }, + "contracts/Lens/PoolLens.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { RewardsDistributor } from \"../Rewards/RewardsDistributor.sol\";\n\n/**\n * @title PoolLens\n * @author Venus\n * @notice The `PoolLens` contract is designed to retrieve important information for each registered pool. A list of essential information\n * for all pools within the lending protocol can be acquired through the function `getAllPools()`. Additionally, the following records can be\n * looked up for specific pools and markets:\n- the vToken balance of a given user;\n- the pool data (oracle address, associated vToken, liquidation incentive, etc) of a pool via its associated comptroller address;\n- the vToken address in a pool for a given asset;\n- a list of all pools that support an asset;\n- the underlying asset price of a vToken;\n- the metadata (exchange/borrow/supply rate, total supply, collateral factor, etc) of any vToken.\n */\ncontract PoolLens is ExponentialNoError {\n /**\n * @dev Struct for PoolDetails.\n */\n struct PoolData {\n string name;\n address creator;\n address comptroller;\n uint256 blockPosted;\n uint256 timestampPosted;\n string category;\n string logoURL;\n string description;\n address priceOracle;\n uint256 closeFactor;\n uint256 liquidationIncentive;\n uint256 minLiquidatableCollateral;\n VTokenMetadata[] vTokens;\n }\n\n /**\n * @dev Struct for VToken.\n */\n struct VTokenMetadata {\n address vToken;\n uint256 exchangeRateCurrent;\n uint256 supplyRatePerBlock;\n uint256 borrowRatePerBlock;\n uint256 reserveFactorMantissa;\n uint256 supplyCaps;\n uint256 borrowCaps;\n uint256 totalBorrows;\n uint256 totalReserves;\n uint256 totalSupply;\n uint256 totalCash;\n bool isListed;\n uint256 collateralFactorMantissa;\n address underlyingAssetAddress;\n uint256 vTokenDecimals;\n uint256 underlyingDecimals;\n }\n\n /**\n * @dev Struct for VTokenBalance.\n */\n struct VTokenBalances {\n address vToken;\n uint256 balanceOf;\n uint256 borrowBalanceCurrent;\n uint256 balanceOfUnderlying;\n uint256 tokenBalance;\n uint256 tokenAllowance;\n }\n\n /**\n * @dev Struct for underlyingPrice of VToken.\n */\n struct VTokenUnderlyingPrice {\n address vToken;\n uint256 underlyingPrice;\n }\n\n /**\n * @dev Struct with pending reward info for a market.\n */\n struct PendingReward {\n address vTokenAddress;\n uint256 amount;\n }\n\n /**\n * @dev Struct with reward distribution totals for a single reward token and distributor.\n */\n struct RewardSummary {\n address distributorAddress;\n address rewardTokenAddress;\n uint256 totalRewards;\n PendingReward[] pendingRewards;\n }\n\n /**\n * @dev Struct used in RewardDistributor to save last updated market state.\n */\n struct RewardTokenState {\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\n uint224 index;\n // The block number the index was last updated at\n uint32 block;\n // The block number at which to stop rewards\n uint32 lastRewardingBlock;\n }\n\n /**\n * @dev Struct with bad debt of a market denominated\n */\n struct BadDebt {\n address vTokenAddress;\n uint256 badDebtUsd;\n }\n\n /**\n * @dev Struct with bad debt total denominated in usd for a pool and an array of BadDebt structs for each market\n */\n struct BadDebtSummary {\n address comptroller;\n uint256 totalBadDebtUsd;\n BadDebt[] badDebts;\n }\n\n /**\n * @notice Queries the user's supply/borrow balances in vTokens\n * @param vTokens The list of vToken addresses\n * @param account The user Account\n * @return A list of structs containing balances data\n */\n function vTokenBalancesAll(VToken[] calldata vTokens, address account) external returns (VTokenBalances[] memory) {\n uint256 vTokenCount = vTokens.length;\n VTokenBalances[] memory res = new VTokenBalances[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenBalances(vTokens[i], account);\n }\n return res;\n }\n\n /**\n * @notice Queries all pools with addtional details for each of them\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @return Arrays of all Venus pools' data\n */\n function getAllPools(address poolRegistryAddress) external view returns (PoolData[] memory) {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n PoolRegistry.VenusPool[] memory venusPools = poolRegistryInterface.getAllPools();\n uint256 poolLength = venusPools.length;\n\n PoolData[] memory poolDataItems = new PoolData[](poolLength);\n\n for (uint256 i; i < poolLength; ++i) {\n PoolRegistry.VenusPool memory venusPool = venusPools[i];\n PoolData memory poolData = getPoolDataFromVenusPool(poolRegistryAddress, venusPool);\n poolDataItems[i] = poolData;\n }\n\n return poolDataItems;\n }\n\n /**\n * @notice Queries the details of a pool identified by Comptroller address\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param comptroller The Comptroller implementation address\n * @return PoolData structure containing the details of the pool\n */\n function getPoolByComptroller(address poolRegistryAddress, address comptroller)\n external\n view\n returns (PoolData memory)\n {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return getPoolDataFromVenusPool(poolRegistryAddress, poolRegistryInterface.getPoolByComptroller(comptroller));\n }\n\n /**\n * @notice Returns vToken holding the specified underlying asset in the specified pool\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param comptroller The pool comptroller\n * @param asset The underlyingAsset of VToken\n * @return Address of the vToken\n */\n function getVTokenForAsset(\n address poolRegistryAddress,\n address comptroller,\n address asset\n ) external view returns (address) {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return poolRegistryInterface.getVTokenForAsset(comptroller, asset);\n }\n\n /**\n * @notice Returns all pools that support the specified underlying asset\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param asset The underlying asset of vToken\n * @return A list of Comptroller contracts\n */\n function getPoolsSupportedByAsset(address poolRegistryAddress, address asset)\n external\n view\n returns (address[] memory)\n {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return poolRegistryInterface.getPoolsSupportedByAsset(asset);\n }\n\n /**\n * @notice Returns the price data for the underlying assets of the specified vTokens\n * @param vTokens The list of vToken addresses\n * @return An array containing the price data for each asset\n */\n function vTokenUnderlyingPriceAll(VToken[] calldata vTokens)\n external\n view\n returns (VTokenUnderlyingPrice[] memory)\n {\n uint256 vTokenCount = vTokens.length;\n VTokenUnderlyingPrice[] memory res = new VTokenUnderlyingPrice[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenUnderlyingPrice(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Returns the pending rewards for a user for a given pool.\n * @param account The user account.\n * @param comptrollerAddress address\n * @return Pending rewards array\n */\n function getPendingRewards(address account, address comptrollerAddress)\n external\n view\n returns (RewardSummary[] memory)\n {\n VToken[] memory markets = ComptrollerInterface(comptrollerAddress).getAllMarkets();\n RewardsDistributor[] memory rewardsDistributors = ComptrollerViewInterface(comptrollerAddress)\n .getRewardDistributors();\n RewardSummary[] memory rewardSummary = new RewardSummary[](rewardsDistributors.length);\n for (uint256 i; i < rewardsDistributors.length; ++i) {\n RewardSummary memory reward;\n reward.distributorAddress = address(rewardsDistributors[i]);\n reward.rewardTokenAddress = address(rewardsDistributors[i].rewardToken());\n reward.totalRewards = rewardsDistributors[i].rewardTokenAccrued(account);\n reward.pendingRewards = _calculateNotDistributedAwards(account, markets, rewardsDistributors[i]);\n rewardSummary[i] = reward;\n }\n return rewardSummary;\n }\n\n /**\n * @notice Returns a summary of a pool's bad debt broken down by market\n *\n * @param comptrollerAddress Address of the comptroller\n *\n * @return badDebtSummary A struct with comptroller address, total bad debut denominated in usd, and\n * a break down of bad debt by market\n */\n function getPoolBadDebt(address comptrollerAddress) external view returns (BadDebtSummary memory) {\n uint256 totalBadDebtUsd;\n\n // Get every market in the pool\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);\n VToken[] memory markets = comptroller.getAllMarkets();\n ResilientOracleInterface priceOracle = comptroller.oracle();\n\n BadDebt[] memory badDebts = new BadDebt[](markets.length);\n\n BadDebtSummary memory badDebtSummary;\n badDebtSummary.comptroller = comptrollerAddress;\n badDebtSummary.badDebts = badDebts;\n\n // // Calculate the bad debt is USD per market\n for (uint256 i; i < markets.length; ++i) {\n BadDebt memory badDebt;\n badDebt.vTokenAddress = address(markets[i]);\n badDebt.badDebtUsd =\n (VToken(address(markets[i])).badDebt() * priceOracle.getUnderlyingPrice(address(markets[i]))) /\n EXP_SCALE;\n badDebtSummary.badDebts[i] = badDebt;\n totalBadDebtUsd = totalBadDebtUsd + badDebt.badDebtUsd;\n }\n\n badDebtSummary.totalBadDebtUsd = totalBadDebtUsd;\n\n return badDebtSummary;\n }\n\n /**\n * @notice Queries the user's supply/borrow balances in the specified vToken\n * @param vToken vToken address\n * @param account The user Account\n * @return A struct containing the balances data\n */\n function vTokenBalances(VToken vToken, address account) public returns (VTokenBalances memory) {\n uint256 balanceOf = vToken.balanceOf(account);\n uint256 borrowBalanceCurrent = vToken.borrowBalanceCurrent(account);\n uint256 balanceOfUnderlying = vToken.balanceOfUnderlying(account);\n uint256 tokenBalance;\n uint256 tokenAllowance;\n\n IERC20 underlying = IERC20(vToken.underlying());\n tokenBalance = underlying.balanceOf(account);\n tokenAllowance = underlying.allowance(account, address(vToken));\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 Queries additional information for the pool\n * @param poolRegistryAddress Address of the PoolRegistry\n * @param venusPool The VenusPool Object from PoolRegistry\n * @return Enriched PoolData\n */\n function getPoolDataFromVenusPool(address poolRegistryAddress, PoolRegistry.VenusPool memory venusPool)\n public\n view\n returns (PoolData memory)\n {\n // Get tokens in the Pool\n ComptrollerInterface comptrollerInstance = ComptrollerInterface(venusPool.comptroller);\n\n VToken[] memory vTokens = comptrollerInstance.getAllMarkets();\n\n VTokenMetadata[] memory vTokenMetadataItems = vTokenMetadataAll(vTokens);\n\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n\n PoolRegistry.VenusPoolMetaData memory venusPoolMetaData = poolRegistryInterface.getVenusPoolMetadata(\n venusPool.comptroller\n );\n\n ComptrollerViewInterface comptrollerViewInstance = ComptrollerViewInterface(venusPool.comptroller);\n\n PoolData memory poolData = PoolData({\n name: venusPool.name,\n creator: venusPool.creator,\n comptroller: venusPool.comptroller,\n blockPosted: venusPool.blockPosted,\n timestampPosted: venusPool.timestampPosted,\n category: venusPoolMetaData.category,\n logoURL: venusPoolMetaData.logoURL,\n description: venusPoolMetaData.description,\n vTokens: vTokenMetadataItems,\n priceOracle: address(comptrollerViewInstance.oracle()),\n closeFactor: comptrollerViewInstance.closeFactorMantissa(),\n liquidationIncentive: comptrollerViewInstance.liquidationIncentiveMantissa(),\n minLiquidatableCollateral: comptrollerViewInstance.minLiquidatableCollateral()\n });\n\n return poolData;\n }\n\n /**\n * @notice Returns the metadata of VToken\n * @param vToken The address of vToken\n * @return VTokenMetadata struct\n */\n function vTokenMetadata(VToken vToken) public view returns (VTokenMetadata memory) {\n uint256 exchangeRateCurrent = vToken.exchangeRateStored();\n address comptrollerAddress = address(vToken.comptroller());\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);\n (bool isListed, uint256 collateralFactorMantissa) = comptroller.markets(address(vToken));\n\n address underlyingAssetAddress = vToken.underlying();\n uint256 underlyingDecimals = IERC20Metadata(underlyingAssetAddress).decimals();\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 supplyCaps: comptroller.supplyCaps(address(vToken)),\n borrowCaps: comptroller.borrowCaps(address(vToken)),\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 });\n }\n\n /**\n * @notice Returns the metadata of all VTokens\n * @param vTokens The list of vToken addresses\n * @return An array of VTokenMetadata structs\n */\n function vTokenMetadataAll(VToken[] memory vTokens) public view returns (VTokenMetadata[] memory) {\n uint256 vTokenCount = vTokens.length;\n VTokenMetadata[] memory res = new VTokenMetadata[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenMetadata(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Returns the price data for the underlying asset of the specified vToken\n * @param vToken vToken address\n * @return The price data for each asset\n */\n function vTokenUnderlyingPrice(VToken vToken) public view returns (VTokenUnderlyingPrice memory) {\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(address(vToken.comptroller()));\n ResilientOracleInterface priceOracle = comptroller.oracle();\n\n return\n VTokenUnderlyingPrice({\n vToken: address(vToken),\n underlyingPrice: priceOracle.getUnderlyingPrice(address(vToken))\n });\n }\n\n function _calculateNotDistributedAwards(\n address account,\n VToken[] memory markets,\n RewardsDistributor rewardsDistributor\n ) internal view returns (PendingReward[] memory) {\n PendingReward[] memory pendingRewards = new PendingReward[](markets.length);\n for (uint256 i; i < markets.length; ++i) {\n // Market borrow and supply state we will modify update in-memory, in order to not modify storage\n RewardTokenState memory borrowState;\n (borrowState.index, borrowState.block, borrowState.lastRewardingBlock) = rewardsDistributor\n .rewardTokenBorrowState(address(markets[i]));\n RewardTokenState memory supplyState;\n (supplyState.index, supplyState.block, supplyState.lastRewardingBlock) = rewardsDistributor\n .rewardTokenSupplyState(address(markets[i]));\n Exp memory marketBorrowIndex = Exp({ mantissa: markets[i].borrowIndex() });\n\n // Update market supply and borrow index in-memory\n updateMarketBorrowIndex(address(markets[i]), rewardsDistributor, borrowState, marketBorrowIndex);\n updateMarketSupplyIndex(address(markets[i]), rewardsDistributor, supplyState);\n\n // Calculate pending rewards\n uint256 borrowReward = calculateBorrowerReward(\n address(markets[i]),\n rewardsDistributor,\n account,\n borrowState,\n marketBorrowIndex\n );\n uint256 supplyReward = calculateSupplierReward(\n address(markets[i]),\n rewardsDistributor,\n account,\n supplyState\n );\n\n PendingReward memory pendingReward;\n pendingReward.vTokenAddress = address(markets[i]);\n pendingReward.amount = borrowReward + supplyReward;\n pendingRewards[i] = pendingReward;\n }\n return pendingRewards;\n }\n\n function updateMarketBorrowIndex(\n address vToken,\n RewardsDistributor rewardsDistributor,\n RewardTokenState memory borrowState,\n Exp memory marketBorrowIndex\n ) internal view {\n uint256 borrowSpeed = rewardsDistributor.rewardTokenBorrowSpeeds(vToken);\n uint256 blockNumber = block.number;\n\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\n blockNumber = borrowState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(blockNumber, uint256(borrowState.block));\n if (deltaBlocks > 0 && borrowSpeed > 0) {\n // Remove the total earned interest rate since the opening of the market from total borrows\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint256 tokensAccrued = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount > 0 ? fraction(tokensAccrued, 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 function updateMarketSupplyIndex(\n address vToken,\n RewardsDistributor rewardsDistributor,\n RewardTokenState memory supplyState\n ) internal view {\n uint256 supplySpeed = rewardsDistributor.rewardTokenSupplySpeeds(vToken);\n uint256 blockNumber = block.number;\n\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\n blockNumber = supplyState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(blockNumber, uint256(supplyState.block));\n if (deltaBlocks > 0 && supplySpeed > 0) {\n uint256 supplyTokens = VToken(vToken).totalSupply();\n uint256 tokensAccrued = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens > 0 ? fraction(tokensAccrued, 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 function calculateBorrowerReward(\n address vToken,\n RewardsDistributor rewardsDistributor,\n address borrower,\n RewardTokenState memory borrowState,\n Exp memory marketBorrowIndex\n ) internal view returns (uint256) {\n Double memory borrowIndex = Double({ mantissa: borrowState.index });\n Double memory borrowerIndex = Double({\n mantissa: rewardsDistributor.rewardTokenBorrowerIndex(vToken, borrower)\n });\n if (borrowerIndex.mantissa == 0 && borrowIndex.mantissa >= rewardsDistributor.INITIAL_INDEX()) {\n // Covers the case where users borrowed tokens before the market's borrow state index was set\n borrowerIndex.mantissa = rewardsDistributor.INITIAL_INDEX();\n }\n Double memory deltaIndex = sub_(borrowIndex, borrowerIndex);\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\n return borrowerDelta;\n }\n\n function calculateSupplierReward(\n address vToken,\n RewardsDistributor rewardsDistributor,\n address supplier,\n RewardTokenState memory supplyState\n ) internal view returns (uint256) {\n Double memory supplyIndex = Double({ mantissa: supplyState.index });\n Double memory supplierIndex = Double({\n mantissa: rewardsDistributor.rewardTokenSupplierIndex(vToken, supplier)\n });\n if (supplierIndex.mantissa == 0 && supplyIndex.mantissa >= rewardsDistributor.INITIAL_INDEX()) {\n // Covers the case where users supplied tokens before the market's supply state index was set\n supplierIndex.mantissa = rewardsDistributor.INITIAL_INDEX();\n }\n Double memory deltaIndex = sub_(supplyIndex, supplierIndex);\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\n return supplierDelta;\n }\n}\n" + }, + "contracts/lib/ApproveOrRevert.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\nlibrary ApproveOrRevert {\n /// @notice Thrown if a contract is unable to approve a transfer\n error ApproveFailed();\n\n /// @notice Approves a transfer, ensuring that it is successful. This function supports non-compliant\n /// tokens like the ones that don't return a boolean value on success. Thus, such approve call supports\n /// three different kinds of tokens:\n /// * Compliant tokens that revert on failure\n /// * Compliant tokens that return false on failure\n /// * Non-compliant tokens that don't return a value\n /// @param token The contract address of the token which will be transferred\n /// @param spender The spender contract address\n /// @param amount The value of the transfer\n function approveOrRevert(\n IERC20Upgradeable token,\n address spender,\n uint256 amount\n ) internal {\n bytes memory callData = abi.encodeCall(token.approve, (spender, amount));\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory result) = address(token).call(callData);\n\n if (!success || (result.length != 0 && !abi.decode(result, (bool)))) {\n revert ApproveFailed();\n }\n }\n}\n" + }, + "contracts/lib/constants.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\n\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\nuint256 constant EXP_SCALE = 1e18;\n\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\nuint256 constant MANTISSA_ONE = EXP_SCALE;\n" + }, + "contracts/lib/TokenDebtTracker.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\n/**\n * @title TokenDebtTracker\n * @author Venus\n * @notice TokenDebtTracker is an abstract contract that handles transfers _out_ of the inheriting contract.\n * If there is an error transferring out (due to any reason, e.g. the token contract restricted the user from\n * receiving incoming transfers), the amount is recorded as a debt that can be claimed later.\n * @dev Note that the inheriting contract keeps some amount of users' tokens on its balance, so be careful when\n * using balanceOf(address(this))!\n */\nabstract contract TokenDebtTracker is Initializable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /**\n * @notice Mapping (IERC20Upgradeable token => (address user => uint256 amount)).\n * Tracks failed transfers: when a token transfer fails, we record the\n * amount of the transfer, so that the user can redeem this debt later.\n */\n mapping(IERC20Upgradeable => mapping(address => uint256)) public tokenDebt;\n\n /**\n * @notice Mapping (IERC20Upgradeable token => uint256 amount) shows how many\n * tokens the contract owes to all users. This is useful for accounting to\n * understand how much of balanceOf(address(this)) is already owed to users.\n */\n mapping(IERC20Upgradeable => uint256) public totalTokenDebt;\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 * @notice Emitted when the contract's debt to the user is increased due to a failed transfer\n * @param token Token address\n * @param user User address\n * @param amount The amount of debt added\n */\n event TokenDebtAdded(address indexed token, address indexed user, uint256 amount);\n\n /**\n * @notice Emitted when a user claims tokens that the contract owes them\n * @param token Token address\n * @param user User address\n * @param amount The amount transferred\n */\n event TokenDebtClaimed(address indexed token, address indexed user, uint256 amount);\n\n /**\n * @notice Thrown if the user tries to claim more tokens than they are owed\n * @param token The token the user is trying to claim\n * @param owedAmount The amount of tokens the contract owes to the user\n * @param amount The amount of tokens the user is trying to claim\n */\n error InsufficientDebt(address token, address user, uint256 owedAmount, uint256 amount);\n\n /**\n * @notice Thrown if trying to transfer more tokens than the contract currently has\n * @param token The token the contract is trying to transfer\n * @param recipient The recipient of the transfer\n * @param amount The amount of tokens the contract is trying to transfer\n * @param availableBalance The amount of tokens the contract currently has\n */\n error InsufficientBalance(address token, address recipient, uint256 amount, uint256 availableBalance);\n\n /**\n * @notice Transfers the tokens we owe to msg.sender, if any\n * @param token The token to claim\n * @param amount_ The amount of tokens to claim (or max uint256 to claim all)\n * @custom:error InsufficientDebt The contract doesn't have enough debt to the user\n */\n function claimTokenDebt(IERC20Upgradeable token, uint256 amount_) external {\n uint256 owedAmount = tokenDebt[token][msg.sender];\n uint256 amount = (amount_ == type(uint256).max ? owedAmount : amount_);\n if (amount > owedAmount) {\n revert InsufficientDebt(address(token), msg.sender, owedAmount, amount);\n }\n unchecked {\n // Safe because we revert if amount > owedAmount above\n tokenDebt[token][msg.sender] = owedAmount - amount;\n }\n totalTokenDebt[token] -= amount;\n emit TokenDebtClaimed(address(token), msg.sender, amount);\n token.safeTransfer(msg.sender, amount);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __TokenDebtTracker_init() internal onlyInitializing {\n __TokenDebtTracker_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __TokenDebtTracker_init_unchained() internal onlyInitializing {}\n\n /**\n * @dev Transfers tokens to the recipient if the contract has enough balance, or\n * records the debt if the transfer fails due to reasons unrelated to the contract's\n * balance (e.g. if the token forbids transfers to the recipient).\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n * @custom:error InsufficientBalance The contract doesn't have enough balance to transfer\n */\n function _transferOutOrTrackDebt(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) internal {\n uint256 balance = token.balanceOf(address(this));\n if (balance < amount) {\n revert InsufficientBalance(address(token), address(this), amount, balance);\n }\n _transferOutOrTrackDebtSkippingBalanceCheck(token, to, amount);\n }\n\n /**\n * @dev Transfers tokens to the recipient, or records the debt if the transfer fails\n * due to any reason, including insufficient balance.\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n */\n function _transferOutOrTrackDebtSkippingBalanceCheck(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) internal {\n // We can't use safeTransfer here because we can't try-catch internal calls\n bool success = _tryTransferOut(token, to, amount);\n if (!success) {\n tokenDebt[token][to] += amount;\n totalTokenDebt[token] += amount;\n emit TokenDebtAdded(address(token), to, amount);\n }\n }\n\n /**\n * @dev Either transfers tokens to the recepient or returns false. Supports tokens\n * thet revert or return false to indicate failure, and the non-compliant ones\n * that do not return any value.\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n * @return true if the transfer succeeded, false otherwise\n */\n function _tryTransferOut(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) private returns (bool) {\n bytes memory callData = abi.encodeCall(token.transfer, (to, amount));\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(callData);\n return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\n }\n}\n" + }, + "contracts/lib/validators.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\nerror ZeroAddressNotAllowed();\n\n/// @notice Checks if the provided address is nonzero, reverts otherwise\n/// @param address_ Address to check\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\nfunction ensureNonzeroAddress(address address_) pure {\n if (address_ == address(0)) {\n revert ZeroAddressNotAllowed();\n }\n}\n" + }, + "contracts/MaxLoopsLimitHelper.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title MaxLoopsLimitHelper\n * @author Venus\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\n */\nabstract contract MaxLoopsLimitHelper {\n // Limit for the loops to avoid the DOS\n uint256 public maxLoopsLimit;\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 max loops limit is set\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\n\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function _setMaxLoopsLimit(uint256 limit) internal {\n require(limit > maxLoopsLimit, \"Comptroller: Invalid maxLoopsLimit\");\n\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\n maxLoopsLimit = limit;\n\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\n }\n\n /**\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\n * @param len Length of the loops iterate\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\n */\n function _ensureMaxLoops(uint256 len) internal view {\n if (len > maxLoopsLimit) {\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\n }\n }\n}\n" + }, + "contracts/Pool/PoolRegistry.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { PoolRegistryInterface } from \"./PoolRegistryInterface.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\n\n/**\n * @title PoolRegistry\n * @author Venus\n * @notice The Isolated Pools architecture centers around the `PoolRegistry` contract. The `PoolRegistry` maintains a directory of isolated lending\n * pools and can perform actions like creating and registering new pools, adding new markets to existing pools, setting and updating the pool's required\n * metadata, and providing the getter methods to get information on the pools.\n *\n * Isolated lending has three main components: PoolRegistry, pools, and markets. The PoolRegistry is responsible for managing pools.\n * It can create new pools, update pool metadata and manage markets within pools. PoolRegistry contains getter methods to get the details of\n * any existing pool like `getVTokenForAsset` and `getPoolsSupportedByAsset`. It also contains methods for updating pool metadata (`updatePoolMetadata`)\n * and setting pool name (`setPoolName`).\n *\n * The directory of pools is managed through two mappings: `_poolByComptroller` which is a hashmap with the comptroller address as the key and `VenusPool` as\n * the value and `_poolsByID` which is an array of comptroller addresses. Individual pools can be accessed by calling `getPoolByComptroller` with the pool's\n * comptroller address. `_poolsByID` is used to iterate through all of the pools.\n *\n * PoolRegistry also contains a map of asset addresses called `_supportedPools` that maps to an array of assets suppored by each pool. This array of pools by\n * asset is retrieved by calling `getPoolsSupportedByAsset`.\n *\n * PoolRegistry registers new isolated pools in the directory with the `createRegistryPool` method. Isolated pools are composed of independent markets with\n * specific assets and custom risk management configurations according to their markets.\n */\ncontract PoolRegistry is Ownable2StepUpgradeable, AccessControlledV8, PoolRegistryInterface {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n struct AddMarketInput {\n VToken vToken;\n uint256 collateralFactor;\n uint256 liquidationThreshold;\n uint256 initialSupply;\n address vTokenReceiver;\n uint256 supplyCap;\n uint256 borrowCap;\n }\n\n uint256 internal constant MAX_POOL_NAME_LENGTH = 100;\n\n /**\n * @notice Maps pool's comptroller address to metadata.\n */\n mapping(address => VenusPoolMetaData) public metadata;\n\n /**\n * @dev Maps pool ID to pool's comptroller address\n */\n mapping(uint256 => address) private _poolsByID;\n\n /**\n * @dev Total number of pools created.\n */\n uint256 private _numberOfPools;\n\n /**\n * @dev Maps comptroller address to Venus pool Index.\n */\n mapping(address => VenusPool) private _poolByComptroller;\n\n /**\n * @dev Maps pool's comptroller address to asset to vToken.\n */\n mapping(address => mapping(address => address)) private _vTokens;\n\n /**\n * @dev Maps asset to list of supported pools.\n */\n mapping(address => address[]) private _supportedPools;\n\n /**\n * @notice Emitted when a new Venus pool is added to the directory.\n */\n event PoolRegistered(address indexed comptroller, VenusPool pool);\n\n /**\n * @notice Emitted when a pool name is set.\n */\n event PoolNameSet(address indexed comptroller, string oldName, string newName);\n\n /**\n * @notice Emitted when a pool metadata is updated.\n */\n event PoolMetadataUpdated(\n address indexed comptroller,\n VenusPoolMetaData oldMetadata,\n VenusPoolMetaData newMetadata\n );\n\n /**\n * @notice Emitted when a Market is added to the pool.\n */\n event MarketAdded(address indexed comptroller, address indexed vTokenAddress);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner\n * @param accessControlManager_ AccessControlManager contract address\n */\n function initialize(address accessControlManager_) external initializer {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n }\n\n /**\n * @notice Adds a new Venus pool to the directory\n * @dev Price oracle must be configured before adding a pool\n * @param name The name of the pool\n * @param comptroller Pool's Comptroller contract\n * @param closeFactor The pool's close factor (scaled by 1e18)\n * @param liquidationIncentive The pool's liquidation incentive (scaled by 1e18)\n * @param minLiquidatableCollateral Minimal collateral for regular (non-batch) liquidations flow\n * @return index The index of the registered Venus pool\n * @custom:error ZeroAddressNotAllowed is thrown when Comptroller address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when price oracle address is zero\n */\n function addPool(\n string calldata name,\n Comptroller comptroller,\n uint256 closeFactor,\n uint256 liquidationIncentive,\n uint256 minLiquidatableCollateral\n ) external virtual returns (uint256 index) {\n _checkAccessAllowed(\"addPool(string,address,uint256,uint256,uint256)\");\n // Input validation\n ensureNonzeroAddress(address(comptroller));\n ensureNonzeroAddress(address(comptroller.oracle()));\n\n uint256 poolId = _registerPool(name, address(comptroller));\n\n // Set Venus pool parameters\n comptroller.setCloseFactor(closeFactor);\n comptroller.setLiquidationIncentive(liquidationIncentive);\n comptroller.setMinLiquidatableCollateral(minLiquidatableCollateral);\n\n return poolId;\n }\n\n /**\n * @notice Add a market to an existing pool and then mint to provide initial supply\n * @param input The structure describing the parameters for adding a market to a pool\n * @custom:error ZeroAddressNotAllowed is thrown when vToken address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when vTokenReceiver address is zero\n */\n function addMarket(AddMarketInput memory input) external {\n _checkAccessAllowed(\"addMarket(AddMarketInput)\");\n ensureNonzeroAddress(address(input.vToken));\n ensureNonzeroAddress(input.vTokenReceiver);\n require(input.initialSupply > 0, \"PoolRegistry: initialSupply is zero\");\n\n VToken vToken = input.vToken;\n address vTokenAddress = address(vToken);\n address comptrollerAddress = address(vToken.comptroller());\n Comptroller comptroller = Comptroller(comptrollerAddress);\n address underlyingAddress = vToken.underlying();\n IERC20Upgradeable underlying = IERC20Upgradeable(underlyingAddress);\n\n require(_poolByComptroller[comptrollerAddress].creator != address(0), \"PoolRegistry: Pool not registered\");\n // solhint-disable-next-line reason-string\n require(\n _vTokens[comptrollerAddress][underlyingAddress] == address(0),\n \"PoolRegistry: Market already added for asset comptroller combination\"\n );\n\n comptroller.supportMarket(vToken);\n comptroller.setCollateralFactor(vToken, input.collateralFactor, input.liquidationThreshold);\n\n uint256[] memory newSupplyCaps = new uint256[](1);\n uint256[] memory newBorrowCaps = new uint256[](1);\n VToken[] memory vTokens = new VToken[](1);\n\n newSupplyCaps[0] = input.supplyCap;\n newBorrowCaps[0] = input.borrowCap;\n vTokens[0] = vToken;\n\n comptroller.setMarketSupplyCaps(vTokens, newSupplyCaps);\n comptroller.setMarketBorrowCaps(vTokens, newBorrowCaps);\n\n _vTokens[comptrollerAddress][underlyingAddress] = vTokenAddress;\n _supportedPools[underlyingAddress].push(comptrollerAddress);\n\n uint256 amountToSupply = _transferIn(underlying, msg.sender, input.initialSupply);\n underlying.approve(vTokenAddress, 0);\n underlying.approve(vTokenAddress, amountToSupply);\n vToken.mintBehalf(input.vTokenReceiver, amountToSupply);\n\n emit MarketAdded(comptrollerAddress, vTokenAddress);\n }\n\n /**\n * @notice Modify existing Venus pool name\n * @param comptroller Pool's Comptroller\n * @param name New pool name\n */\n function setPoolName(address comptroller, string calldata name) external {\n _checkAccessAllowed(\"setPoolName(address,string)\");\n _ensureValidName(name);\n VenusPool storage pool = _poolByComptroller[comptroller];\n string memory oldName = pool.name;\n pool.name = name;\n emit PoolNameSet(comptroller, oldName, name);\n }\n\n /**\n * @notice Update metadata of an existing pool\n * @param comptroller Pool's Comptroller\n * @param metadata_ New pool metadata\n */\n function updatePoolMetadata(address comptroller, VenusPoolMetaData calldata metadata_) external {\n _checkAccessAllowed(\"updatePoolMetadata(address,VenusPoolMetaData)\");\n VenusPoolMetaData memory oldMetadata = metadata[comptroller];\n metadata[comptroller] = metadata_;\n emit PoolMetadataUpdated(comptroller, oldMetadata, metadata_);\n }\n\n /**\n * @notice Returns arrays of all Venus pools' data\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\n * @return A list of all pools within PoolRegistry, with details for each pool\n */\n function getAllPools() external view override returns (VenusPool[] memory) {\n uint256 numberOfPools_ = _numberOfPools; // storage load to save gas\n VenusPool[] memory _pools = new VenusPool[](numberOfPools_);\n for (uint256 i = 1; i <= numberOfPools_; ++i) {\n address comptroller = _poolsByID[i];\n _pools[i - 1] = (_poolByComptroller[comptroller]);\n }\n return _pools;\n }\n\n /**\n * @param comptroller The comptroller proxy address associated to the pool\n * @return Returns Venus pool\n */\n function getPoolByComptroller(address comptroller) external view override returns (VenusPool memory) {\n return _poolByComptroller[comptroller];\n }\n\n /**\n * @param comptroller comptroller of Venus pool\n * @return Returns Metadata of Venus pool\n */\n function getVenusPoolMetadata(address comptroller) external view override returns (VenusPoolMetaData memory) {\n return metadata[comptroller];\n }\n\n function getVTokenForAsset(address comptroller, address asset) external view override returns (address) {\n return _vTokens[comptroller][asset];\n }\n\n function getPoolsSupportedByAsset(address asset) external view override returns (address[] memory) {\n return _supportedPools[asset];\n }\n\n /**\n * @dev Adds a new Venus pool to the directory (without checking msg.sender).\n * @param name The name of the pool\n * @param comptroller The pool's Comptroller proxy contract address\n * @return The index of the registered Venus pool\n */\n function _registerPool(string calldata name, address comptroller) internal returns (uint256) {\n VenusPool storage storedPool = _poolByComptroller[comptroller];\n\n require(storedPool.creator == address(0), \"PoolRegistry: Pool already exists in the directory.\");\n _ensureValidName(name);\n\n ++_numberOfPools;\n uint256 numberOfPools_ = _numberOfPools; // cache on stack to save storage read gas\n\n VenusPool memory pool = VenusPool(name, msg.sender, comptroller, block.number, block.timestamp);\n\n _poolsByID[numberOfPools_] = comptroller;\n _poolByComptroller[comptroller] = pool;\n\n emit PoolRegistered(comptroller, pool);\n return numberOfPools_;\n }\n\n function _transferIn(\n IERC20Upgradeable token,\n address from,\n uint256 amount\n ) internal returns (uint256) {\n uint256 balanceBefore = token.balanceOf(address(this));\n token.safeTransferFrom(from, address(this), amount);\n uint256 balanceAfter = token.balanceOf(address(this));\n return balanceAfter - balanceBefore;\n }\n\n function _ensureValidName(string calldata name) internal pure {\n require(bytes(name).length <= MAX_POOL_NAME_LENGTH, \"Pool's name is too large\");\n }\n}\n" + }, + "contracts/Pool/PoolRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title PoolRegistryInterface\n * @author Venus\n * @notice Interface implemented by `PoolRegistry`.\n */\ninterface PoolRegistryInterface {\n /**\n * @notice Struct for a Venus interest rate pool.\n */\n struct VenusPool {\n string name;\n address creator;\n address comptroller;\n uint256 blockPosted;\n uint256 timestampPosted;\n }\n\n /**\n * @notice Struct for a Venus interest rate pool metadata.\n */\n struct VenusPoolMetaData {\n string category;\n string logoURL;\n string description;\n }\n\n /// @notice Get all pools in PoolRegistry\n function getAllPools() external view returns (VenusPool[] memory);\n\n /// @notice Get a pool by comptroller address\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\n\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\n\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\n\n /// @notice Get the metadata of a Pool by comptroller address\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\n}\n" + }, + "contracts/Rewards/RewardsDistributor.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { MaxLoopsLimitHelper } from \"../MaxLoopsLimitHelper.sol\";\n\n/**\n * @title `RewardsDistributor`\n * @author Venus\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\n * token to be released each block for borrowers and suppliers, which is distributed based on a user’s percentage of the borrows or supplies\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\n *\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\n */\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n struct RewardToken {\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\n uint224 index;\n // The block number the index was last updated at\n uint32 block;\n // The block number at which to stop rewards\n uint32 lastRewardingBlock;\n }\n\n /// @notice The initial REWARD TOKEN index for a market\n uint224 public constant INITIAL_INDEX = 1e36;\n\n /// @notice The REWARD TOKEN market supply state for each market\n mapping(address => RewardToken) public rewardTokenSupplyState;\n\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\n\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\n mapping(address => uint256) public rewardTokenAccrued;\n\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\n\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\n mapping(address => uint256) public rewardTokenSupplySpeeds;\n\n /// @notice The REWARD TOKEN market borrow state for each market\n mapping(address => RewardToken) public rewardTokenBorrowState;\n\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\n mapping(address => uint256) public rewardTokenContributorSpeeds;\n\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\n mapping(address => uint256) public lastContributorBlock;\n\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\n\n Comptroller private comptroller;\n\n IERC20Upgradeable public rewardToken;\n\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\n event DistributedSupplierRewardToken(\n VToken indexed vToken,\n address indexed supplier,\n uint256 rewardTokenDelta,\n uint256 rewardTokenTotal,\n uint256 rewardTokenSupplyIndex\n );\n\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\n event DistributedBorrowerRewardToken(\n VToken indexed vToken,\n address indexed borrower,\n uint256 rewardTokenDelta,\n uint256 rewardTokenTotal,\n uint256 rewardTokenBorrowIndex\n );\n\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /// @notice Emitted when REWARD TOKEN is granted by admin\n event RewardTokenGranted(address indexed recipient, uint256 amount);\n\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\n\n /// @notice Emitted when a market is initialized\n event MarketInitialized(address indexed vToken);\n\n /// @notice Emitted when a reward token supply index is updated\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\n\n /// @notice Emitted when a reward token borrow index is updated\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\n\n /// @notice Emitted when a reward for contributor is updated\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\n\n /// @notice Emitted when a reward token last rewarding block for supply is updated\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\n\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\n\n modifier onlyComptroller() {\n require(address(comptroller) == msg.sender, \"Only comptroller can call this function\");\n _;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice RewardsDistributor initializer\n * @dev Initializes the deployer to owner\n * @param comptroller_ Comptroller to attach the reward distributor to\n * @param rewardToken_ Reward token to distribute\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\n * @param accessControlManager_ AccessControlManager contract address\n */\n function initialize(\n Comptroller comptroller_,\n IERC20Upgradeable rewardToken_,\n uint256 loopsLimit_,\n address accessControlManager_\n ) external initializer {\n comptroller = comptroller_;\n rewardToken = rewardToken_;\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n\n _setMaxLoopsLimit(loopsLimit_);\n }\n\n function initializeMarket(address vToken) external onlyComptroller {\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\n }\n\n if (borrowState.index == 0) {\n // Initialize borrow state index with default value\n borrowState.index = INITIAL_INDEX;\n }\n\n /*\n * Update market state block numbers\n */\n supplyState.block = borrowState.block = blockNumber;\n\n emit MarketInitialized(vToken);\n }\n\n /*** Reward Token Distribution ***/\n\n /**\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\n * Borrowers will begin to accrue after the first interaction with the protocol.\n * @dev This function should only be called when the user has a borrow position in the market\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\n * @param vToken The market in which the borrower is interacting\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\n * @param marketBorrowIndex The current global borrow index of vToken\n */\n function distributeBorrowerRewardToken(\n address vToken,\n address borrower,\n Exp memory marketBorrowIndex\n ) external onlyComptroller {\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\n }\n\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\n _updateRewardTokenSupplyIndex(vToken);\n }\n\n /**\n * @notice Transfer REWARD TOKEN to the recipient\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\n */\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\n uint256 amountLeft = _grantRewardToken(recipient, amount);\n require(amountLeft == 0, \"insufficient rewardToken for grant\");\n emit RewardTokenGranted(recipient, amount);\n }\n\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\n }\n\n /**\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\n * @param vTokens The markets whose REWARD TOKEN speed to update\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\n */\n function setRewardTokenSpeeds(\n VToken[] memory vTokens,\n uint256[] memory supplySpeeds,\n uint256[] memory borrowSpeeds\n ) external {\n _checkAccessAllowed(\"setRewardTokenSpeeds(address[],uint256[],uint256[])\");\n uint256 numTokens = vTokens.length;\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \"invalid setRewardTokenSpeeds\");\n\n for (uint256 i; i < numTokens; ++i) {\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\n }\n }\n\n /**\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\n */\n function setLastRewardingBlocks(\n VToken[] calldata vTokens,\n uint32[] calldata supplyLastRewardingBlocks,\n uint32[] calldata borrowLastRewardingBlocks\n ) external {\n _checkAccessAllowed(\"setLastRewardingBlock(address[],uint32[],uint32[])\");\n uint256 numTokens = vTokens.length;\n require(\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\n \"RewardsDistributor::setLastRewardingBlocks invalid input\"\n );\n\n for (uint256 i; i < numTokens; ) {\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Set REWARD TOKEN speed for a single contributor\n * @param contributor The contributor whose REWARD TOKEN speed to update\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\n */\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\n updateContributorRewards(contributor);\n if (rewardTokenSpeed == 0) {\n // release storage\n delete lastContributorBlock[contributor];\n } else {\n lastContributorBlock[contributor] = getBlockNumber();\n }\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\n\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\n }\n\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\n _distributeSupplierRewardToken(vToken, supplier);\n }\n\n /**\n * @notice Claim all the rewardToken accrued by holder in all markets\n * @param holder The address to claim REWARD TOKEN for\n */\n function claimRewardToken(address holder) external {\n return claimRewardToken(holder, comptroller.getAllMarkets());\n }\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\n * @param contributor The address to calculate contributor rewards for\n */\n function updateContributorRewards(address contributor) public {\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\n uint256 blockNumber = getBlockNumber();\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\n\n rewardTokenAccrued[contributor] = contributorAccrued;\n lastContributorBlock[contributor] = blockNumber;\n\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\n }\n }\n\n /**\n * @notice Claim all the rewardToken accrued by holder in the specified markets\n * @param holder The address to claim REWARD TOKEN for\n * @param vTokens The list of markets to claim REWARD TOKEN in\n */\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\n uint256 vTokensCount = vTokens.length;\n\n _ensureMaxLoops(vTokensCount);\n\n for (uint256 i; i < vTokensCount; ++i) {\n VToken vToken = vTokens[i];\n require(comptroller.isMarketListed(vToken), \"market must be listed\");\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\n _updateRewardTokenSupplyIndex(address(vToken));\n _distributeSupplierRewardToken(address(vToken), holder);\n }\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\n }\n\n function getBlockNumber() public view virtual returns (uint256) {\n return block.number;\n }\n\n /**\n * @notice Set REWARD TOKEN last rewarding block for a single market.\n * @param vToken market's whose reward token last rewarding block to be updated\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\n */\n function _setLastRewardingBlock(\n VToken vToken,\n uint32 supplyLastRewardingBlock,\n uint32 borrowLastRewardingBlock\n ) internal {\n require(comptroller.isMarketListed(vToken), \"rewardToken market is not listed\");\n\n uint256 blockNumber = getBlockNumber();\n\n require(supplyLastRewardingBlock > blockNumber, \"setting last rewarding block in the past is not allowed\");\n require(borrowLastRewardingBlock > blockNumber, \"setting last rewarding block in the past is not allowed\");\n\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\n\n require(\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\n \"this RewardsDistributor is already locked\"\n );\n require(\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\n \"this RewardsDistributor is already locked\"\n );\n\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\n }\n\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\n }\n }\n\n /**\n * @notice Set REWARD TOKEN speed for a single market.\n * @param vToken market's whose reward token rate to be updated\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\n */\n function _setRewardTokenSpeed(\n VToken vToken,\n uint256 supplySpeed,\n uint256 borrowSpeed\n ) internal {\n require(comptroller.isMarketListed(vToken), \"rewardToken market is not listed\");\n\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\n // Supply speed updated so let's update supply state to ensure that\n // 1. REWARD TOKEN accrued properly for the old speed, and\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\n _updateRewardTokenSupplyIndex(address(vToken));\n\n // Update speed and emit event\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\n }\n\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\n // Borrow speed updated so let's update borrow state to ensure that\n // 1. REWARD TOKEN accrued properly for the old speed, and\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\n\n // Update speed and emit event\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\n }\n }\n\n /**\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\n */\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n uint256 supplyIndex = supplyState.index;\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\n\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\n\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\n // Covers the case where users supplied tokens before the market's supply state index was set.\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\n // set for the market.\n supplierIndex = INITIAL_INDEX;\n }\n\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\n\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\n\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\n\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\n rewardTokenAccrued[supplier] = supplierAccrued;\n\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\n }\n\n /**\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\n * @param vToken The market in which the borrower is interacting\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\n * @param marketBorrowIndex The current global borrow index of vToken\n */\n function _distributeBorrowerRewardToken(\n address vToken,\n address borrower,\n Exp memory marketBorrowIndex\n ) internal {\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\n uint256 borrowIndex = borrowState.index;\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\n\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\n\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\n // set for the market.\n borrowerIndex = INITIAL_INDEX;\n }\n\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\n\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\n\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\n if (borrowerAmount != 0) {\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\n\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\n rewardTokenAccrued[borrower] = borrowerAccrued;\n\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\n }\n }\n\n /**\n * @notice Transfer REWARD TOKEN to the user.\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\n * @param user The address of the user to transfer REWARD TOKEN to\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\n */\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\n if (amount > 0 && amount <= rewardTokenRemaining) {\n rewardToken.safeTransfer(user, amount);\n return 0;\n }\n return amount;\n }\n\n /**\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\n * @param vToken The market whose supply index to update\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\n */\n function _updateRewardTokenSupplyIndex(address vToken) internal {\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\n blockNumber = supplyState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\n\n if (deltaBlocks > 0 && supplySpeed > 0) {\n uint256 supplyTokens = VToken(vToken).totalSupply();\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens > 0\n ? fraction(accruedSinceUpdate, supplyTokens)\n : Double({ mantissa: 0 });\n supplyState.index = safe224(\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\n \"new index exceeds 224 bits\"\n );\n supplyState.block = blockNumber;\n } else if (deltaBlocks > 0) {\n supplyState.block = blockNumber;\n }\n\n emit RewardTokenSupplyIndexUpdated(vToken);\n }\n\n /**\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\n * @param vToken The market whose borrow index to update\n * @param marketBorrowIndex The current global borrow index of vToken\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\n */\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\n blockNumber = borrowState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\n if (deltaBlocks > 0 && borrowSpeed > 0) {\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount > 0\n ? fraction(accruedSinceUpdate, borrowAmount)\n : Double({ mantissa: 0 });\n borrowState.index = safe224(\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\n \"new index exceeds 224 bits\"\n );\n borrowState.block = blockNumber;\n } else if (deltaBlocks > 0) {\n borrowState.block = blockNumber;\n }\n\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\n }\n}\n" + }, + "contracts/RiskFund/IProtocolShareReserve.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title IProtocolShareReserve\n * @author Venus\n * @notice Interface implemented by `ProtocolShareReserve`.\n */\ninterface IProtocolShareReserve {\n function updateAssetsState(address comptroller, address asset) external;\n}\n" + }, + "contracts/RiskFund/IRiskFund.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title IRiskFund\n * @author Venus\n * @notice Interface implemented by `RiskFund`.\n */\ninterface IRiskFund {\n function swapPoolsAssets(\n address[] calldata markets,\n uint256[] calldata amountsOutMin,\n address[][] calldata paths,\n uint256 deadline\n ) external returns (uint256);\n\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\n\n function updateAssetsState(address comptroller, address asset) external;\n\n function convertibleBaseAsset() external view returns (address);\n\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\n}\n" + }, + "contracts/RiskFund/ProtocolShareReserve.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\nimport { IProtocolShareReserve } from \"./IProtocolShareReserve.sol\";\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { ReserveHelpers } from \"./ReserveHelpers.sol\";\nimport { IRiskFund } from \"./IRiskFund.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\n\ncontract ProtocolShareReserve is ExponentialNoError, ReserveHelpers, IProtocolShareReserve {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n address public protocolIncome;\n address public riskFund;\n // Percentage of funds not sent to the RiskFund contract when the funds are released, following the project Tokenomics\n uint256 private constant PROTOCOL_SHARE_PERCENTAGE = 50;\n uint256 private constant BASE_UNIT = 100;\n\n /// @notice Emitted when funds are released\n event FundsReleased(address indexed comptroller, address indexed asset, uint256 amount);\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner.\n * @param protocolIncome_ The address protocol income will be sent to\n * @param riskFund_ Risk fund address\n * @custom:error ZeroAddressNotAllowed is thrown when protocol income address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\n */\n function initialize(address protocolIncome_, address riskFund_) external initializer {\n ensureNonzeroAddress(protocolIncome_);\n ensureNonzeroAddress(riskFund_);\n\n __Ownable2Step_init();\n\n protocolIncome = protocolIncome_;\n riskFund = riskFund_;\n }\n\n /**\n * @notice Pool registry setter.\n * @param poolRegistry_ Address of the pool registry\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Release funds\n * @param comptroller Pool's Comptroller\n * @param asset Asset to be released\n * @param amount Amount to release\n * @return Number of total released tokens\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function releaseFunds(\n address comptroller,\n address asset,\n uint256 amount\n ) external nonReentrant returns (uint256) {\n ensureNonzeroAddress(asset);\n require(amount <= _poolsAssetsReserves[comptroller][asset], \"ProtocolShareReserve: Insufficient pool balance\");\n\n assetsReserves[asset] -= amount;\n _poolsAssetsReserves[comptroller][asset] -= amount;\n uint256 protocolIncomeAmount = mul_(\n Exp({ mantissa: amount }),\n div_(Exp({ mantissa: PROTOCOL_SHARE_PERCENTAGE * EXP_SCALE }), BASE_UNIT)\n ).mantissa;\n\n address riskFund_ = riskFund;\n\n emit FundsReleased(comptroller, asset, amount);\n\n IERC20Upgradeable(asset).safeTransfer(protocolIncome, protocolIncomeAmount);\n IERC20Upgradeable(asset).safeTransfer(riskFund_, amount - protocolIncomeAmount);\n\n // Update the pool asset's state in the risk fund for the above transfer.\n IRiskFund(riskFund_).updateAssetsState(comptroller, asset);\n\n return amount;\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to the protocol share reserve.\n * @param comptroller Comptroller address(pool)\n * @param asset Asset address.\n */\n function updateAssetsState(address comptroller, address asset)\n public\n override(IProtocolShareReserve, ReserveHelpers)\n {\n super.updateAssetsState(comptroller, asset);\n }\n}\n" + }, + "contracts/RiskFund/ReserveHelpers.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\n\ncontract ReserveHelpers is Ownable2StepUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n uint256 private constant NOT_ENTERED = 1;\n\n uint256 private constant ENTERED = 2;\n\n // Store the previous state for the asset transferred to ProtocolShareReserve combined(for all pools).\n mapping(address => uint256) public assetsReserves;\n\n // Store the asset's reserve per pool in the ProtocolShareReserve.\n // Comptroller(pool) -> Asset -> amount\n mapping(address => mapping(address => uint256)) internal _poolsAssetsReserves;\n\n // Address of pool registry contract\n address public poolRegistry;\n\n /**\n * @dev Guard variable for re-entrancy checks\n */\n uint256 internal status;\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 */\n uint256[46] private __gap;\n\n /// @notice Event emitted after the update of the assets reserves.\n /// @param comptroller Pool's Comptroller address\n /// @param asset Token address\n /// @param amount An amount by which the reserves have increased\n event AssetsReservesUpdated(address indexed comptroller, address indexed asset, uint256 amount);\n\n /// @notice event emitted on sweep token success\n event SweepToken(address indexed token, address indexed to, uint256 amount);\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(status != ENTERED, \"re-entered\");\n status = ENTERED;\n _;\n status = NOT_ENTERED;\n }\n\n /**\n * @notice A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\n * @param _token The address of the BEP-20 token to sweep\n * @param _to Recipient of the output tokens.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n * @custom:access Only Owner\n */\n function sweepToken(address _token, address _to) external onlyOwner nonReentrant {\n ensureNonzeroAddress(_to);\n uint256 balanceDfference_;\n uint256 balance_ = IERC20Upgradeable(_token).balanceOf(address(this));\n\n require(balance_ > assetsReserves[_token], \"ReserveHelpers: Zero surplus tokens\");\n unchecked {\n balanceDfference_ = balance_ - assetsReserves[_token];\n }\n\n emit SweepToken(_token, _to, balanceDfference_);\n IERC20Upgradeable(_token).safeTransfer(_to, balanceDfference_);\n }\n\n /**\n * @notice Get the Amount of the asset in the risk fund for the specific pool.\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n * @return Asset's reserve in risk fund.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function getPoolAssetReserve(address comptroller, address asset) external view returns (uint256) {\n ensureNonzeroAddress(asset);\n require(ComptrollerInterface(comptroller).isComptroller(), \"ReserveHelpers: Comptroller address invalid\");\n return _poolsAssetsReserves[comptroller][asset];\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund\n * and transferring funds to the protocol share reserve\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function updateAssetsState(address comptroller, address asset) public virtual {\n ensureNonzeroAddress(asset);\n require(ComptrollerInterface(comptroller).isComptroller(), \"ReserveHelpers: Comptroller address invalid\");\n address poolRegistry_ = poolRegistry;\n require(poolRegistry_ != address(0), \"ReserveHelpers: Pool Registry address is not set\");\n require(\n PoolRegistryInterface(poolRegistry_).getVTokenForAsset(comptroller, asset) != address(0),\n \"ReserveHelpers: The pool doesn't support the asset\"\n );\n\n uint256 currentBalance = IERC20Upgradeable(asset).balanceOf(address(this));\n uint256 assetReserve = assetsReserves[asset];\n if (currentBalance > assetReserve) {\n uint256 balanceDifference;\n unchecked {\n balanceDifference = currentBalance - assetReserve;\n }\n assetsReserves[asset] += balanceDifference;\n _poolsAssetsReserves[comptroller][asset] += balanceDifference;\n emit AssetsReservesUpdated(comptroller, asset, balanceDifference);\n }\n }\n}\n" + }, + "contracts/RiskFund/RiskFund.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { IRiskFund } from \"./IRiskFund.sol\";\nimport { ReserveHelpers } from \"./ReserveHelpers.sol\";\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { IPancakeswapV2Router } from \"../IPancakeswapV2Router.sol\";\nimport { MaxLoopsLimitHelper } from \"../MaxLoopsLimitHelper.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\nimport { ApproveOrRevert } from \"../lib/ApproveOrRevert.sol\";\n\n/**\n * @title RiskFund\n * @author Venus\n * @notice Contract with basic features to track/hold different assets for different Comptrollers.\n * @dev This contract does not support BNB.\n */\ncontract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, MaxLoopsLimitHelper, IRiskFund {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using ApproveOrRevert for IERC20Upgradeable;\n\n address public convertibleBaseAsset;\n address public shortfall;\n address public pancakeSwapRouter;\n uint256 public minAmountToConvert;\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @notice Emitted when shortfall contract address is updated\n event ShortfallContractUpdated(address indexed oldShortfallContract, address indexed newShortfallContract);\n\n /// @notice Emitted when convertible base asset is updated\n event ConvertibleBaseAssetUpdated(address indexed oldConvertibleBaseAsset, address indexed newConvertibleBaseAsset);\n\n /// @notice Emitted when PancakeSwap router contract address is updated\n event PancakeSwapRouterUpdated(address indexed oldPancakeSwapRouter, address indexed newPancakeSwapRouter);\n\n /// @notice Emitted when minimum amount to convert is updated\n event MinAmountToConvertUpdated(uint256 oldMinAmountToConvert, uint256 newMinAmountToConvert);\n\n /// @notice Emitted when pools assets are swapped\n event SwappedPoolsAssets(address[] markets, uint256[] amountsOutMin, uint256 totalAmount);\n\n /// @notice Emitted when reserves are transferred for auction\n event TransferredReserveForAuction(address indexed comptroller, uint256 amount);\n\n /// @dev Note that the contract is upgradeable. Use initialize() or reinitializers\n /// to set the state variables.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner.\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\n * @param minAmountToConvert_ Minimum amount assets must be worth to convert into base asset\n * @param convertibleBaseAsset_ Address of the base asset\n * @param accessControlManager_ Address of the access control contract\n * @param loopsLimit_ Limit for the loops in the contract to avoid DOS\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\n */\n function initialize(\n address pancakeSwapRouter_,\n uint256 minAmountToConvert_,\n address convertibleBaseAsset_,\n address accessControlManager_,\n uint256 loopsLimit_\n ) external initializer {\n ensureNonzeroAddress(pancakeSwapRouter_);\n ensureNonzeroAddress(convertibleBaseAsset_);\n require(minAmountToConvert_ > 0, \"Risk Fund: Invalid min amount to convert\");\n require(loopsLimit_ > 0, \"Risk Fund: Loops limit can not be zero\");\n\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n\n pancakeSwapRouter = pancakeSwapRouter_;\n minAmountToConvert = minAmountToConvert_;\n convertibleBaseAsset = convertibleBaseAsset_;\n\n _setMaxLoopsLimit(loopsLimit_);\n }\n\n /**\n * @notice Pool registry setter\n * @param poolRegistry_ Address of the pool registry\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Shortfall contract address setter\n * @param shortfallContractAddress_ Address of the auction contract\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n */\n function setShortfallContractAddress(address shortfallContractAddress_) external onlyOwner {\n ensureNonzeroAddress(shortfallContractAddress_);\n\n address oldShortfallContractAddress = shortfall;\n shortfall = shortfallContractAddress_;\n emit ShortfallContractUpdated(oldShortfallContractAddress, shortfallContractAddress_);\n }\n\n /**\n * @notice PancakeSwap router address setter\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\n */\n function setPancakeSwapRouter(address pancakeSwapRouter_) external onlyOwner {\n ensureNonzeroAddress(pancakeSwapRouter_);\n address oldPancakeSwapRouter = pancakeSwapRouter;\n pancakeSwapRouter = pancakeSwapRouter_;\n emit PancakeSwapRouterUpdated(oldPancakeSwapRouter, pancakeSwapRouter_);\n }\n\n /**\n * @notice Min amount to convert setter\n * @param minAmountToConvert_ Min amount to convert.\n */\n function setMinAmountToConvert(uint256 minAmountToConvert_) external {\n _checkAccessAllowed(\"setMinAmountToConvert(uint256)\");\n require(minAmountToConvert_ > 0, \"Risk Fund: Invalid min amount to convert\");\n uint256 oldMinAmountToConvert = minAmountToConvert;\n minAmountToConvert = minAmountToConvert_;\n emit MinAmountToConvertUpdated(oldMinAmountToConvert, minAmountToConvert_);\n }\n\n /**\n * @notice Sets a new convertible base asset\n * @param _convertibleBaseAsset Address for new convertible base asset.\n */\n function setConvertibleBaseAsset(address _convertibleBaseAsset) external {\n _checkAccessAllowed(\"setConvertibleBaseAsset(address)\");\n require(_convertibleBaseAsset != address(0), \"Risk Fund: new convertible base asset address invalid\");\n\n address oldConvertibleBaseAsset = convertibleBaseAsset;\n convertibleBaseAsset = _convertibleBaseAsset;\n\n emit ConvertibleBaseAssetUpdated(oldConvertibleBaseAsset, _convertibleBaseAsset);\n }\n\n /**\n * @notice Swap array of pool assets into base asset's tokens of at least a minimum amount\n * @param markets Array of vTokens whose assets to swap for base asset\n * @param amountsOutMin Minimum amount to receive for swap\n * @param paths A path consisting of PCS token pairs for each swap\n * @param deadline Deadline for the swap\n * @return Number of swapped tokens\n * @custom:error ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured\n */\n function swapPoolsAssets(\n address[] calldata markets,\n uint256[] calldata amountsOutMin,\n address[][] calldata paths,\n uint256 deadline\n ) external override nonReentrant returns (uint256) {\n _checkAccessAllowed(\"swapPoolsAssets(address[],uint256[],address[][],uint256)\");\n require(deadline >= block.timestamp, \"Risk fund: deadline passed\");\n address poolRegistry_ = poolRegistry;\n ensureNonzeroAddress(poolRegistry_);\n require(markets.length == amountsOutMin.length, \"Risk fund: markets and amountsOutMin are unequal lengths\");\n require(markets.length == paths.length, \"Risk fund: markets and paths are unequal lengths\");\n\n uint256 totalAmount;\n uint256 marketsCount = markets.length;\n\n _ensureMaxLoops(marketsCount);\n\n for (uint256 i; i < marketsCount; ++i) {\n address comptroller = address(VToken(markets[i]).comptroller());\n\n PoolRegistry.VenusPool memory pool = PoolRegistry(poolRegistry_).getPoolByComptroller(comptroller);\n require(pool.comptroller == comptroller, \"comptroller doesn't exist pool registry\");\n require(Comptroller(comptroller).isMarketListed(VToken(markets[i])), \"market is not listed\");\n\n uint256 swappedTokens = _swapAsset(VToken(markets[i]), comptroller, amountsOutMin[i], paths[i]);\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] += swappedTokens;\n assetsReserves[convertibleBaseAsset] += swappedTokens;\n totalAmount = totalAmount + swappedTokens;\n }\n\n emit SwappedPoolsAssets(markets, amountsOutMin, totalAmount);\n\n return totalAmount;\n }\n\n /**\n * @notice Transfer tokens for auction.\n * @param comptroller Comptroller of the pool.\n * @param amount Amount to be transferred to auction contract.\n * @return Number reserved tokens.\n */\n function transferReserveForAuction(address comptroller, uint256 amount)\n external\n override\n nonReentrant\n returns (uint256)\n {\n address shortfall_ = shortfall;\n require(msg.sender == shortfall_, \"Risk fund: Only callable by Shortfall contract\");\n require(\n amount <= _poolsAssetsReserves[comptroller][convertibleBaseAsset],\n \"Risk Fund: Insufficient pool reserve.\"\n );\n unchecked {\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] =\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] -\n amount;\n }\n unchecked {\n assetsReserves[convertibleBaseAsset] = assetsReserves[convertibleBaseAsset] - amount;\n }\n\n emit TransferredReserveForAuction(comptroller, amount);\n IERC20Upgradeable(convertibleBaseAsset).safeTransfer(shortfall_, amount);\n\n return amount;\n }\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Get the Amount of the Base asset in the risk fund for the specific pool.\n * @param comptroller Comptroller address(pool).\n * @return Base Asset's reserve in risk fund.\n */\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256) {\n require(ComptrollerInterface(comptroller).isComptroller(), \"Risk Fund: Comptroller address invalid\");\n return _poolsAssetsReserves[comptroller][convertibleBaseAsset];\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund.\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n */\n function updateAssetsState(address comptroller, address asset) public override(IRiskFund, ReserveHelpers) {\n super.updateAssetsState(comptroller, asset);\n }\n\n /**\n * @dev Swap single asset to base asset.\n * @param vToken VToken\n * @param comptroller Comptroller address\n * @param amountOutMin Minimum amount to receive for swap\n * @param path A path for the swap consisting of PCS token pairs\n * @return Number of swapped tokens.\n */\n function _swapAsset(\n VToken vToken,\n address comptroller,\n uint256 amountOutMin,\n address[] calldata path\n ) internal returns (uint256) {\n require(amountOutMin != 0, \"RiskFund: amountOutMin must be greater than 0 to swap vToken\");\n uint256 totalAmount;\n\n address underlyingAsset = vToken.underlying();\n address convertibleBaseAsset_ = convertibleBaseAsset;\n uint256 balanceOfUnderlyingAsset = _poolsAssetsReserves[comptroller][underlyingAsset];\n\n if (balanceOfUnderlyingAsset == 0) {\n return 0;\n }\n\n ResilientOracleInterface oracle = ComptrollerViewInterface(comptroller).oracle();\n oracle.updateAssetPrice(convertibleBaseAsset_);\n Exp memory baseAssetPrice = Exp({ mantissa: oracle.getPrice(convertibleBaseAsset_) });\n uint256 amountOutMinInUsd = mul_ScalarTruncate(baseAssetPrice, amountOutMin);\n\n require(amountOutMinInUsd >= minAmountToConvert, \"RiskFund: minAmountToConvert violated\");\n\n assetsReserves[underlyingAsset] -= balanceOfUnderlyingAsset;\n _poolsAssetsReserves[comptroller][underlyingAsset] -= balanceOfUnderlyingAsset;\n\n if (underlyingAsset != convertibleBaseAsset_) {\n require(path[0] == underlyingAsset, \"RiskFund: swap path must start with the underlying asset\");\n require(\n path[path.length - 1] == convertibleBaseAsset_,\n \"RiskFund: finally path must be convertible base asset\"\n );\n address pancakeSwapRouter_ = pancakeSwapRouter;\n IERC20Upgradeable(underlyingAsset).approveOrRevert(pancakeSwapRouter_, 0);\n IERC20Upgradeable(underlyingAsset).approveOrRevert(pancakeSwapRouter_, balanceOfUnderlyingAsset);\n uint256[] memory amounts = IPancakeswapV2Router(pancakeSwapRouter_).swapExactTokensForTokens(\n balanceOfUnderlyingAsset,\n amountOutMin,\n path,\n address(this),\n block.timestamp\n );\n totalAmount = amounts[path.length - 1];\n } else {\n totalAmount = balanceOfUnderlyingAsset;\n }\n\n return totalAmount;\n }\n}\n" + }, + "contracts/Shortfall/Shortfall.sol": { + "content": "/// @notice SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { ReentrancyGuardUpgradeable } from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { IRiskFund } from \"../RiskFund/IRiskFund.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\nimport { TokenDebtTracker } from \"../lib/TokenDebtTracker.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\nimport { EXP_SCALE } from \"../lib/constants.sol\";\n\n/**\n * @title Shortfall\n * @author Venus\n * @notice Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset`\n * is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value.\n * This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner\n * is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise,\n * if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the\n * risk fund in exchange for paying off all the pool's bad debt.\n */\ncontract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGuardUpgradeable, TokenDebtTracker {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /// @notice Type of auction\n enum AuctionType {\n LARGE_POOL_DEBT,\n LARGE_RISK_FUND\n }\n\n /// @notice Status of auction\n enum AuctionStatus {\n NOT_STARTED,\n STARTED,\n ENDED\n }\n\n /// @notice Auction metadata\n struct Auction {\n uint256 startBlock;\n AuctionType auctionType;\n AuctionStatus status;\n VToken[] markets;\n uint256 seizedRiskFund;\n address highestBidder;\n uint256 highestBidBps;\n uint256 highestBidBlock;\n uint256 startBidBps;\n mapping(VToken => uint256) marketDebt;\n mapping(VToken => uint256) bidAmount;\n }\n\n /// @dev Max basis points i.e., 100%\n uint256 private constant MAX_BPS = 10000;\n\n uint256 private constant DEFAULT_NEXT_BIDDER_BLOCK_LIMIT = 100;\n\n uint256 private constant DEFAULT_WAIT_FOR_FIRST_BIDDER = 100;\n\n uint256 private constant DEFAULT_INCENTIVE_BPS = 1000; // 10%\n\n /// @notice Pool registry address\n address public poolRegistry;\n\n /// @notice Risk fund address\n IRiskFund public riskFund;\n\n /// @notice Minimum USD debt in pool for shortfall to trigger\n uint256 public minimumPoolBadDebt;\n\n /// @notice Incentive to auction participants, initial value set to 1000 or 10%\n uint256 public incentiveBps;\n\n /// @notice Time to wait for next bidder. Initially waits for 100 blocks\n uint256 public nextBidderBlockLimit;\n\n /// @notice Boolean of if auctions are paused\n bool public auctionsPaused;\n\n /// @notice Time to wait for first bidder. Initially waits for 100 blocks\n uint256 public waitForFirstBidder;\n\n /// @notice Auctions for each pool\n mapping(address => Auction) public auctions;\n\n /// @notice Emitted when a auction starts\n event AuctionStarted(\n address indexed comptroller,\n uint256 auctionStartBlock,\n AuctionType auctionType,\n VToken[] markets,\n uint256[] marketsDebt,\n uint256 seizedRiskFund,\n uint256 startBidBps\n );\n\n /// @notice Emitted when a bid is placed\n event BidPlaced(address indexed comptroller, uint256 auctionStartBlock, uint256 bidBps, address indexed bidder);\n\n /// @notice Emitted when a auction is completed\n event AuctionClosed(\n address indexed comptroller,\n uint256 auctionStartBlock,\n address indexed highestBidder,\n uint256 highestBidBps,\n uint256 seizedRiskFind,\n VToken[] markets,\n uint256[] marketDebt\n );\n\n /// @notice Emitted when a auction is restarted\n event AuctionRestarted(address indexed comptroller, uint256 auctionStartBlock);\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @notice Emitted when minimum pool bad debt is updated\n event MinimumPoolBadDebtUpdated(uint256 oldMinimumPoolBadDebt, uint256 newMinimumPoolBadDebt);\n\n /// @notice Emitted when wait for first bidder block count is updated\n event WaitForFirstBidderUpdated(uint256 oldWaitForFirstBidder, uint256 newWaitForFirstBidder);\n\n /// @notice Emitted when next bidder block limit is updated\n event NextBidderBlockLimitUpdated(uint256 oldNextBidderBlockLimit, uint256 newNextBidderBlockLimit);\n\n /// @notice Emitted when incentiveBps is updated\n event IncentiveBpsUpdated(uint256 oldIncentiveBps, uint256 newIncentiveBps);\n\n /// @notice Emitted when auctions are paused\n event AuctionsPaused(address sender);\n\n /// @notice Emitted when auctions are unpaused\n event AuctionsResumed(address sender);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initialize the shortfall contract\n * @param riskFund_ RiskFund contract address\n * @param minimumPoolBadDebt_ Minimum bad debt in base asset for a pool to start auction\n * @param accessControlManager_ AccessControlManager contract address\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\n */\n function initialize(\n IRiskFund riskFund_,\n uint256 minimumPoolBadDebt_,\n address accessControlManager_\n ) external initializer {\n ensureNonzeroAddress(address(riskFund_));\n require(minimumPoolBadDebt_ != 0, \"invalid minimum pool bad debt\");\n\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n __ReentrancyGuard_init();\n __TokenDebtTracker_init();\n minimumPoolBadDebt = minimumPoolBadDebt_;\n riskFund = riskFund_;\n waitForFirstBidder = DEFAULT_WAIT_FOR_FIRST_BIDDER;\n nextBidderBlockLimit = DEFAULT_NEXT_BIDDER_BLOCK_LIMIT;\n incentiveBps = DEFAULT_INCENTIVE_BPS;\n auctionsPaused = false;\n }\n\n /**\n * @notice Place a bid greater than the previous in an ongoing auction\n * @param comptroller Comptroller address of the pool\n * @param bidBps The bid percent of the risk fund or bad debt depending on auction type\n * @param auctionStartBlock The block number when auction started\n * @custom:event Emits BidPlaced event on success\n */\n function placeBid(\n address comptroller,\n uint256 bidBps,\n uint256 auctionStartBlock\n ) external nonReentrant {\n Auction storage auction = auctions[comptroller];\n\n require(auction.startBlock == auctionStartBlock, \"auction has been restarted\");\n require(_isStarted(auction), \"no on-going auction\");\n require(!_isStale(auction), \"auction is stale, restart it\");\n require(bidBps > 0, \"basis points cannot be zero\");\n require(bidBps <= MAX_BPS, \"basis points cannot be more than 10000\");\n require(\n (auction.auctionType == AuctionType.LARGE_POOL_DEBT &&\n ((auction.highestBidder != address(0) && bidBps > auction.highestBidBps) ||\n (auction.highestBidder == address(0) && bidBps >= auction.startBidBps))) ||\n (auction.auctionType == AuctionType.LARGE_RISK_FUND &&\n ((auction.highestBidder != address(0) && bidBps < auction.highestBidBps) ||\n (auction.highestBidder == address(0) && bidBps <= auction.startBidBps))),\n \"your bid is not the highest\"\n );\n\n uint256 marketsCount = auction.markets.length;\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = VToken(address(auction.markets[i]));\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\n\n if (auction.highestBidder != address(0)) {\n _transferOutOrTrackDebt(erc20, auction.highestBidder, auction.bidAmount[auction.markets[i]]);\n }\n uint256 balanceBefore = erc20.balanceOf(address(this));\n\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\n uint256 currentBidAmount = ((auction.marketDebt[auction.markets[i]] * bidBps) / MAX_BPS);\n erc20.safeTransferFrom(msg.sender, address(this), currentBidAmount);\n } else {\n erc20.safeTransferFrom(msg.sender, address(this), auction.marketDebt[auction.markets[i]]);\n }\n\n uint256 balanceAfter = erc20.balanceOf(address(this));\n auction.bidAmount[auction.markets[i]] = balanceAfter - balanceBefore;\n }\n\n auction.highestBidder = msg.sender;\n auction.highestBidBps = bidBps;\n auction.highestBidBlock = block.number;\n\n emit BidPlaced(comptroller, auction.startBlock, bidBps, msg.sender);\n }\n\n /**\n * @notice Close an auction\n * @param comptroller Comptroller address of the pool\n * @custom:event Emits AuctionClosed event on successful close\n */\n function closeAuction(address comptroller) external nonReentrant {\n Auction storage auction = auctions[comptroller];\n\n require(_isStarted(auction), \"no on-going auction\");\n require(\n block.number > auction.highestBidBlock + nextBidderBlockLimit && auction.highestBidder != address(0),\n \"waiting for next bidder. cannot close auction\"\n );\n\n uint256 marketsCount = auction.markets.length;\n uint256[] memory marketsDebt = new uint256[](marketsCount);\n\n auction.status = AuctionStatus.ENDED;\n\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = VToken(address(auction.markets[i]));\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\n\n uint256 balanceBefore = erc20.balanceOf(address(auction.markets[i]));\n erc20.safeTransfer(address(auction.markets[i]), auction.bidAmount[auction.markets[i]]);\n uint256 balanceAfter = erc20.balanceOf(address(auction.markets[i]));\n marketsDebt[i] = balanceAfter - balanceBefore;\n\n auction.markets[i].badDebtRecovered(marketsDebt[i]);\n }\n\n uint256 riskFundBidAmount;\n\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\n riskFundBidAmount = auction.seizedRiskFund;\n } else {\n riskFundBidAmount = (auction.seizedRiskFund * auction.highestBidBps) / MAX_BPS;\n }\n\n address convertibleBaseAsset = riskFund.convertibleBaseAsset();\n\n uint256 transferredAmount = riskFund.transferReserveForAuction(comptroller, riskFundBidAmount);\n _transferOutOrTrackDebt(IERC20Upgradeable(convertibleBaseAsset), auction.highestBidder, riskFundBidAmount);\n\n emit AuctionClosed(\n comptroller,\n auction.startBlock,\n auction.highestBidder,\n auction.highestBidBps,\n transferredAmount,\n auction.markets,\n marketsDebt\n );\n }\n\n /**\n * @notice Start a auction when there is not currently one active\n * @param comptroller Comptroller address of the pool\n * @custom:event Emits AuctionStarted event on success\n * @custom:event Errors if auctions are paused\n */\n function startAuction(address comptroller) external nonReentrant {\n require(!auctionsPaused, \"Auctions are paused\");\n _startAuction(comptroller);\n }\n\n /**\n * @notice Restart an auction\n * @param comptroller Address of the pool\n * @custom:event Emits AuctionRestarted event on successful restart\n */\n function restartAuction(address comptroller) external nonReentrant {\n Auction storage auction = auctions[comptroller];\n\n require(!auctionsPaused, \"auctions are paused\");\n require(_isStarted(auction), \"no on-going auction\");\n require(_isStale(auction), \"you need to wait for more time for first bidder\");\n\n auction.status = AuctionStatus.ENDED;\n\n emit AuctionRestarted(comptroller, auction.startBlock);\n _startAuction(comptroller);\n }\n\n /**\n * @notice Update next bidder block limit which is used determine when an auction can be closed\n * @param _nextBidderBlockLimit New next bidder block limit\n * @custom:event Emits NextBidderBlockLimitUpdated on success\n * @custom:access Restricted by ACM\n */\n function updateNextBidderBlockLimit(uint256 _nextBidderBlockLimit) external {\n _checkAccessAllowed(\"updateNextBidderBlockLimit(uint256)\");\n require(_nextBidderBlockLimit != 0, \"_nextBidderBlockLimit must not be 0\");\n uint256 oldNextBidderBlockLimit = nextBidderBlockLimit;\n nextBidderBlockLimit = _nextBidderBlockLimit;\n emit NextBidderBlockLimitUpdated(oldNextBidderBlockLimit, _nextBidderBlockLimit);\n }\n\n /**\n * @notice Updates the incentive BPS\n * @param _incentiveBps New incentive BPS\n * @custom:event Emits IncentiveBpsUpdated on success\n * @custom:access Restricted by ACM\n */\n function updateIncentiveBps(uint256 _incentiveBps) external {\n _checkAccessAllowed(\"updateIncentiveBps(uint256)\");\n require(_incentiveBps != 0, \"incentiveBps must not be 0\");\n uint256 oldIncentiveBps = incentiveBps;\n incentiveBps = _incentiveBps;\n emit IncentiveBpsUpdated(oldIncentiveBps, _incentiveBps);\n }\n\n /**\n * @notice Update minimum pool bad debt to start auction\n * @param _minimumPoolBadDebt Minimum bad debt in BUSD for a pool to start auction\n * @custom:event Emits MinimumPoolBadDebtUpdated on success\n * @custom:access Restricted by ACM\n */\n function updateMinimumPoolBadDebt(uint256 _minimumPoolBadDebt) external {\n _checkAccessAllowed(\"updateMinimumPoolBadDebt(uint256)\");\n uint256 oldMinimumPoolBadDebt = minimumPoolBadDebt;\n minimumPoolBadDebt = _minimumPoolBadDebt;\n emit MinimumPoolBadDebtUpdated(oldMinimumPoolBadDebt, _minimumPoolBadDebt);\n }\n\n /**\n * @notice Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted\n * @param _waitForFirstBidder New wait for first bidder block count\n * @custom:event Emits WaitForFirstBidderUpdated on success\n * @custom:access Restricted by ACM\n */\n function updateWaitForFirstBidder(uint256 _waitForFirstBidder) external {\n _checkAccessAllowed(\"updateWaitForFirstBidder(uint256)\");\n uint256 oldWaitForFirstBidder = waitForFirstBidder;\n waitForFirstBidder = _waitForFirstBidder;\n emit WaitForFirstBidderUpdated(oldWaitForFirstBidder, _waitForFirstBidder);\n }\n\n /**\n * @notice Update the pool registry this shortfall supports\n * @dev After Pool Registry is deployed we need to set the pool registry address\n * @param poolRegistry_ Address of pool registry contract\n * @custom:event Emits PoolRegistryUpdated on success\n * @custom:access Restricted to owner\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function updatePoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Pause auctions. This disables starting new auctions but lets the current auction finishes\n * @custom:event Emits AuctionsPaused on success\n * @custom:error Errors is auctions are paused\n * @custom:access Restricted by ACM\n */\n function pauseAuctions() external {\n _checkAccessAllowed(\"pauseAuctions()\");\n require(!auctionsPaused, \"Auctions are already paused\");\n auctionsPaused = true;\n emit AuctionsPaused(msg.sender);\n }\n\n /**\n * @notice Resume paused auctions.\n * @custom:event Emits AuctionsResumed on success\n * @custom:error Errors is auctions are active\n * @custom:access Restricted by ACM\n */\n function resumeAuctions() external {\n _checkAccessAllowed(\"resumeAuctions()\");\n require(auctionsPaused, \"Auctions are not paused\");\n auctionsPaused = false;\n emit AuctionsResumed(msg.sender);\n }\n\n /**\n * @notice Start a auction when there is not currently one active\n * @param comptroller Comptroller address of the pool\n */\n function _startAuction(address comptroller) internal {\n PoolRegistryInterface.VenusPool memory pool = PoolRegistry(poolRegistry).getPoolByComptroller(comptroller);\n require(pool.comptroller == comptroller, \"comptroller doesn't exist pool registry\");\n\n Auction storage auction = auctions[comptroller];\n require(\n auction.status == AuctionStatus.NOT_STARTED || auction.status == AuctionStatus.ENDED,\n \"auction is on-going\"\n );\n\n auction.highestBidBps = 0;\n auction.highestBidBlock = 0;\n\n uint256 marketsCount = auction.markets.length;\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = auction.markets[i];\n auction.marketDebt[vToken] = 0;\n }\n\n delete auction.markets;\n\n VToken[] memory vTokens = _getAllMarkets(comptroller);\n marketsCount = vTokens.length;\n ResilientOracleInterface priceOracle = _getPriceOracle(comptroller);\n uint256 poolBadDebt;\n\n uint256[] memory marketsDebt = new uint256[](marketsCount);\n auction.markets = new VToken[](marketsCount);\n\n for (uint256 i; i < marketsCount; ++i) {\n uint256 marketBadDebt = vTokens[i].badDebt();\n\n priceOracle.updatePrice(address(vTokens[i]));\n uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / EXP_SCALE;\n\n poolBadDebt = poolBadDebt + usdValue;\n auction.markets[i] = vTokens[i];\n auction.marketDebt[vTokens[i]] = marketBadDebt;\n marketsDebt[i] = marketBadDebt;\n }\n\n require(poolBadDebt >= minimumPoolBadDebt, \"pool bad debt is too low\");\n\n priceOracle.updateAssetPrice(riskFund.convertibleBaseAsset());\n uint256 riskFundBalance = (priceOracle.getPrice(riskFund.convertibleBaseAsset()) *\n riskFund.getPoolsBaseAssetReserves(comptroller)) / EXP_SCALE;\n uint256 remainingRiskFundBalance = riskFundBalance;\n uint256 badDebtPlusIncentive = poolBadDebt + ((poolBadDebt * incentiveBps) / MAX_BPS);\n if (badDebtPlusIncentive >= riskFundBalance) {\n auction.startBidBps =\n (MAX_BPS * MAX_BPS * remainingRiskFundBalance) /\n (poolBadDebt * (MAX_BPS + incentiveBps));\n remainingRiskFundBalance = 0;\n auction.auctionType = AuctionType.LARGE_POOL_DEBT;\n } else {\n uint256 maxSeizeableRiskFundBalance = badDebtPlusIncentive;\n\n remainingRiskFundBalance = remainingRiskFundBalance - maxSeizeableRiskFundBalance;\n auction.auctionType = AuctionType.LARGE_RISK_FUND;\n auction.startBidBps = MAX_BPS;\n }\n\n auction.seizedRiskFund = riskFundBalance - remainingRiskFundBalance;\n auction.startBlock = block.number;\n auction.status = AuctionStatus.STARTED;\n auction.highestBidder = address(0);\n\n emit AuctionStarted(\n comptroller,\n auction.startBlock,\n auction.auctionType,\n auction.markets,\n marketsDebt,\n auction.seizedRiskFund,\n auction.startBidBps\n );\n }\n\n /**\n * @dev Returns the price oracle of the pool\n * @param comptroller Address of the pool's comptroller\n * @return oracle The pool's price oracle\n */\n function _getPriceOracle(address comptroller) internal view returns (ResilientOracleInterface) {\n return ResilientOracleInterface(ComptrollerViewInterface(comptroller).oracle());\n }\n\n /**\n * @dev Returns all markets of the pool\n * @param comptroller Address of the pool's comptroller\n * @return markets The pool's markets as VToken array\n */\n function _getAllMarkets(address comptroller) internal view returns (VToken[] memory) {\n return ComptrollerInterface(comptroller).getAllMarkets();\n }\n\n /**\n * @dev Checks if the auction has started\n * @param auction The auction to query the status for\n * @return True if the auction has started\n */\n function _isStarted(Auction storage auction) internal view returns (bool) {\n return auction.status == AuctionStatus.STARTED;\n }\n\n /**\n * @dev Checks if the auction is stale, i.e. there's no bidder and the auction\n * was started more than waitForFirstBidder blocks ago.\n * @param auction The auction to query the status for\n * @return True if the auction is stale\n */\n function _isStale(Auction storage auction) internal view returns (bool) {\n bool noBidder = auction.highestBidder == address(0);\n return noBidder && (block.number > auction.startBlock + waitForFirstBidder);\n }\n}\n" + }, + "contracts/test/ComptrollerHarness.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { Comptroller } from \"../Comptroller.sol\";\n\ncontract ComptrollerHarness is Comptroller {\n uint256 public blockNumber;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address _poolRegistry) Comptroller(_poolRegistry) {}\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\ncontract EchoTypesComptroller {\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(uint256[] memory u) public pure returns (uint256[] memory) {\n return u;\n }\n\n function reverty() public pure {\n require(false, \"gotcha sucka\");\n }\n}\n" + }, + "contracts/test/ComptrollerScenario.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { VToken } from \"../VToken.sol\";\n\ncontract ComptrollerScenario is Comptroller {\n uint256 public blockNumber;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address _poolRegistry) Comptroller(_poolRegistry) {}\n\n function fastForward(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 unlist(VToken vToken) public {\n markets[address(vToken)].isListed = false;\n }\n\n function membershipLength(VToken vToken) public view returns (uint256) {\n return accountAssets[address(vToken)].length;\n }\n}\n" + }, + "contracts/test/Mocks/MockPriceOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { BinanceOracle } from \"@venusprotocol/oracle/contracts/oracles/BinanceOracle.sol\";\nimport { ChainlinkOracle } from \"@venusprotocol/oracle/contracts/oracles/ChainlinkOracle.sol\";\n\nimport { VToken } from \"../../VToken.sol\";\n\ncontract MockPriceOracle is ResilientOracleInterface {\n mapping(address => uint256) public assetPrices;\n\n //set price in 6 decimal precision\n // solhint-disable-next-line no-empty-blocks\n constructor() {}\n\n function setPrice(address asset, uint256 price) external {\n assetPrices[asset] = price;\n }\n\n // solhint-disable-next-line no-empty-blocks\n function updatePrice(address vToken) external override {}\n\n // solhint-disable-next-line no-empty-blocks\n function updateAssetPrice(address asset) external override {}\n\n function getPrice(address asset) external view returns (uint256) {\n return assetPrices[asset];\n }\n\n //https://compound.finance/docs/prices\n function getUnderlyingPrice(address vToken) public view override returns (uint256) {\n return assetPrices[VToken(vToken).underlying()];\n }\n}\n" + }, + "contracts/test/UpgradedVToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { AccessControlManager } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol\";\n\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { InterestRateModel } from \"../InterestRateModel.sol\";\n\n/**\n * @title Venus's VToken Contract\n * @notice VTokens which wrap an EIP-20 underlying and are immutable\n * @author Venus\n */\ncontract UpgradedVToken is VToken {\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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param riskManagement Addresses of risk fund contracts\n */\n\n /// @notice We added this new function to test contract upgrade\n function version() external pure returns (uint256) {\n return 2;\n }\n\n function initializeV2(\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 accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) public reinitializer(2) {\n super._initialize(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_,\n accessControlManager_,\n riskManagement,\n reserveFactorMantissa_\n );\n }\n\n function getTokenUnderlying() public view returns (address) {\n return underlying;\n }\n}\n" + }, + "contracts/test/VTokenHarness.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { AccessControlManager } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol\";\n\nimport { VToken } from \"../VToken.sol\";\nimport { InterestRateModel } from \"../InterestRateModel.sol\";\n\ncontract VTokenHarness is VToken {\n uint256 public blockNumber;\n uint256 public harnessExchangeRate;\n bool public harnessExchangeRateStored;\n\n mapping(address => bool) public failTransferToAddresses;\n\n function harnessSetAccrualBlockNumber(uint256 accrualBlockNumber_) external {\n accrualBlockNumber = accrualBlockNumber_;\n }\n\n function harnessSetBlockNumber(uint256 newBlockNumber) external {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint256 blocks) external {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint256 amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetTotalSupply(uint256 totalSupply_) external {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint256 totalBorrows_) external {\n totalBorrows = totalBorrows_;\n }\n\n function harnessSetTotalReserves(uint256 totalReserves_) external {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(\n uint256 totalSupply_,\n uint256 totalBorrows_,\n uint256 totalReserves_\n ) external {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint256 exchangeRate) external {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address to_, bool fail_) external {\n failTransferToAddresses[to_] = fail_;\n }\n\n function harnessMintFresh(address account, uint256 mintAmount) external {\n super._mintFresh(account, account, mintAmount);\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint256 vTokenAmount,\n uint256 underlyingAmount\n ) external {\n super._redeemFresh(account, vTokenAmount, underlyingAmount);\n }\n\n function harnessSetAccountBorrows(\n address account,\n uint256 principal,\n uint256 interestIndex\n ) external {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint256 borrowIndex_) external {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint256 borrowAmount) external {\n _borrowFresh(account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(\n address payer,\n address account,\n uint256 repayAmount\n ) external {\n _repayBorrowFresh(payer, account, repayAmount);\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VToken vTokenCollateral,\n bool skipLiquidityCheck\n ) external {\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\n }\n\n function harnessReduceReservesFresh(uint256 amount) external {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint256 newReserveFactorMantissa) external {\n _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) external {\n _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessAccountBorrows(address account) external view returns (uint256 principal, uint256 interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function getBorrowRateMaxMantissa() external pure returns (uint256) {\n return MAX_BORROW_RATE_MANTISSA;\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallPreBorrowHook(uint256 amount) public {\n comptroller.preBorrowHook(address(this), msg.sender, amount);\n }\n\n function _doTransferOut(address to, uint256 amount) internal override {\n require(failTransferToAddresses[to] == false, \"HARNESS_TOKEN_TRANSFER_OUT_FAILED\");\n return super._doTransferOut(to, amount);\n }\n\n function _exchangeRateStored() internal view override returns (uint256) {\n if (harnessExchangeRateStored) {\n return harnessExchangeRate;\n }\n return super._exchangeRateStored();\n }\n\n function _getBlockNumber() internal view override returns (uint256) {\n return blockNumber;\n }\n}\n" + }, + "contracts/VToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { VTokenInterface } from \"./VTokenInterfaces.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"./ComptrollerInterface.sol\";\nimport { TokenErrorReporter } from \"./ErrorReporter.sol\";\nimport { InterestRateModel } from \"./InterestRateModel.sol\";\nimport { ExponentialNoError } from \"./ExponentialNoError.sol\";\nimport { IProtocolShareReserve } from \"./RiskFund/IProtocolShareReserve.sol\";\nimport { ensureNonzeroAddress } from \"./lib/validators.sol\";\n\n/**\n * @title VToken\n * @author Venus\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\n * the pool. The main actions a user regularly interacts with in a market are:\n\n- mint/redeem of vTokens;\n- transfer of vTokens;\n- borrow/repay a loan on an underlying asset;\n- liquidate a borrow or liquidate/heal an account.\n\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\n * a user may borrow up to a portion of their collateral determined by the market’s collateral factor. However, if their borrowed amount exceeds an amount\n * calculated using the market’s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\n * pay off interest accrued on the borrow.\n * \n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\n * Both functions settle all of an account’s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\n */\ncontract VToken is\n Ownable2StepUpgradeable,\n AccessControlledV8,\n VTokenInterface,\n ExponentialNoError,\n TokenErrorReporter\n{\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\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 /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param accessControlManager_ AccessControlManager contract address\n * @param riskManagement Addresses of risk & income related contracts\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\n */\n function initialize(\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 admin_,\n address accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) external initializer {\n ensureNonzeroAddress(admin_);\n\n // Initialize the market\n _initialize(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_,\n accessControlManager_,\n riskManagement,\n reserveFactorMantissa_\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 * @return success True if the transfer succeeded, reverts otherwise\n * @custom:event Emits Transfer event on success\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\n * @custom:access Not restricted\n */\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\n * @return success True if the transfer succeeded, reverts otherwise\n * @custom:event Emits Transfer event on success\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\n * @custom:access Not restricted\n */\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) external override nonReentrant returns (bool) {\n _transferTokens(msg.sender, src, dst, amount);\n return true;\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 (uint256.max means infinite)\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function approve(address spender, uint256 amount) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n transferAllowances[src][spender] = amount;\n emit Approval(src, spender, amount);\n return true;\n }\n\n /**\n * @notice Increase approval for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param addedValue The number of additional tokens spender can transfer\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n uint256 newAllowance = transferAllowances[src][spender];\n newAllowance += addedValue;\n transferAllowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n return true;\n }\n\n /**\n * @notice Decreases approval for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param subtractedValue The number of tokens to remove from total approval\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n uint256 currentAllowance = transferAllowances[src][spender];\n require(currentAllowance >= subtractedValue, \"decreased allowance below zero\");\n unchecked {\n currentAllowance -= subtractedValue;\n }\n\n transferAllowances[src][spender] = currentAllowance;\n\n emit Approval(src, spender, currentAllowance);\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 amount The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external override returns (uint256) {\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return totalBorrows The total borrows with interest\n */\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\n accrueInterest();\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 borrowBalance The calculated balance\n */\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\n accrueInterest();\n return _borrowBalanceStored(account);\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n _mintFresh(msg.sender, msg.sender, mintAmount);\n return NO_ERROR;\n }\n\n /**\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param minter User whom the supply will be attributed to\n * @param mintAmount The amount of the underlying asset to supply\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\n */\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\n ensureNonzeroAddress(minter);\n\n accrueInterest();\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n _mintFresh(msg.sender, minter, mintAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\n * @custom:access Not restricted\n */\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\n _redeemFresh(msg.sender, redeemTokens, 0);\n return NO_ERROR;\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 receive from redeeming vTokens\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n */\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\n _redeemFresh(msg.sender, 0, redeemAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Borrow event; may emit AccrueInterest\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\n * @custom:access Not restricted\n */\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\n _borrowFresh(msg.sender, borrowAmount);\n return NO_ERROR;\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\n return NO_ERROR;\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, or type(uint256).max for the full outstanding amount\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\n * @custom:access Not restricted\n */\n function liquidateBorrow(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external override returns (uint256) {\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\n return NO_ERROR;\n }\n\n /**\n * @notice sets protocol share accumulated from liquidations\n * @dev must be equal or less than liquidation incentive - 1\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\n * @custom:event Emits NewProtocolSeizeShare event on success\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\n * @custom:access Controlled by AccessControlManager\n */\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\n _checkAccessAllowed(\"setProtocolSeizeShare(uint256)\");\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\n revert ProtocolSeizeShareTooBig();\n }\n\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\n * @custom:access Controlled by AccessControlManager\n */\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\n _checkAccessAllowed(\"setReserveFactor(uint256)\");\n\n accrueInterest();\n _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\n * @param reduceAmount Amount of reduction to reserves\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\n * @custom:access Not restricted\n */\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\n accrueInterest();\n _reduceReservesFresh(reduceAmount);\n }\n\n /**\n * @notice The sender adds to reserves.\n * @param addAmount The amount of underlying token to add as reserves\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function addReserves(uint256 addAmount) external override nonReentrant {\n accrueInterest();\n _addReservesFresh(addAmount);\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:access Controlled by AccessControlManager\n */\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\n _checkAccessAllowed(\"setInterestRateModel(address)\");\n\n accrueInterest();\n _setInterestRateModelFresh(newInterestRateModel);\n }\n\n /**\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\n * \"forgiving\" the borrower. Healing is a situation that should rarely happen. However, some pools\n * may list risky assets or be configured improperly – we want to still handle such cases gracefully.\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\n * @dev This function does not call any Comptroller hooks (like \"healAllowed\"), because we assume\n * the Comptroller does all the necessary checks before calling this function.\n * @param payer account who repays the debt\n * @param borrower account to heal\n * @param repayAmount amount to repay\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\n * @custom:access Only Comptroller\n */\n function healBorrow(\n address payer,\n address borrower,\n uint256 repayAmount\n ) external override nonReentrant {\n if (repayAmount != 0) {\n comptroller.preRepayHook(address(this), borrower);\n }\n\n if (msg.sender != address(comptroller)) {\n revert HealBorrowUnauthorized();\n }\n\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n uint256 totalBorrowsNew = totalBorrows;\n\n uint256 actualRepayAmount;\n if (repayAmount != 0) {\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\n actualRepayAmount = _doTransferIn(payer, repayAmount);\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\n emit RepayBorrow(\n payer,\n borrower,\n actualRepayAmount,\n accountBorrowsPrev - actualRepayAmount,\n totalBorrowsNew\n );\n }\n\n // The transaction will fail if trying to repay too much\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\n if (badDebtDelta != 0) {\n uint256 badDebtOld = badDebt;\n uint256 badDebtNew = badDebtOld + badDebtDelta;\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\n badDebt = badDebtNew;\n\n // We treat healing as \"repayment\", where vToken is the payer\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\n }\n\n accountBorrows[borrower].principal = 0;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n emit HealBorrow(payer, borrower, repayAmount);\n }\n\n /**\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\n * the close factor check. The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\n * @custom:access Only Comptroller\n */\n function forceLiquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) external override {\n if (msg.sender != address(comptroller)) {\n revert ForceLiquidateBorrowUnauthorized();\n }\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\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 * @custom:event Emits Transfer, ReservesAdded events\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:access Not restricted\n */\n function seize(\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external override nonReentrant {\n _seize(msg.sender, liquidator, borrower, seizeTokens);\n }\n\n /**\n * @notice Updates bad debt\n * @dev Called only when bad debt is recovered from auction\n * @param recoveredAmount_ The amount of bad debt recovered\n * @custom:event Emits BadDebtRecovered event\n * @custom:access Only Shortfall contract\n */\n function badDebtRecovered(uint256 recoveredAmount_) external {\n require(msg.sender == shortfall, \"only shortfall contract can update bad debt\");\n require(recoveredAmount_ <= badDebt, \"more than bad debt recovered from auction\");\n\n uint256 badDebtOld = badDebt;\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\n badDebt = badDebtNew;\n\n emit BadDebtRecovered(badDebtOld, badDebtNew);\n }\n\n /**\n * @notice Sets protocol share reserve contract address\n * @param protocolShareReserve_ The address of the protocol share reserve contract\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\n * @custom:access Only Governance\n */\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\n _setProtocolShareReserve(protocolShareReserve_);\n }\n\n /**\n * @notice Sets shortfall contract address\n * @param shortfall_ The address of the shortfall contract\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n * @custom:access Only Governance\n */\n function setShortfallContract(address shortfall_) external onlyOwner {\n _setShortfallContract(shortfall_);\n }\n\n /**\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\n * @param token The address of the ERC-20 token to sweep\n * @custom:access Only Governance\n */\n function sweepToken(IERC20Upgradeable token) external override {\n require(msg.sender == owner(), \"VToken::sweepToken: only admin can sweep tokens\");\n require(address(token) != underlying, \"VToken::sweepToken: can not sweep underlying token\");\n uint256 balance = token.balanceOf(address(this));\n token.safeTransfer(owner(), balance);\n\n emit SweepToken(address(token));\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\n */\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return vTokenBalance User's balance of vTokens\n * @return borrowBalance Amount owed in terms of underlying\n * @return exchangeRate Stored exchange rate\n */\n function getAccountSnapshot(address account)\n external\n view\n override\n returns (\n uint256 error,\n uint256 vTokenBalance,\n uint256 borrowBalance,\n uint256 exchangeRate\n )\n {\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return cash The quantity of underlying asset owned by this contract\n */\n function getCash() external view override returns (uint256) {\n return _getCashPrior();\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return rate The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view override returns (uint256) {\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this v\n * @return rate The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view override returns (uint256) {\n return\n interestRateModel.getSupplyRate(\n _getCashPrior(),\n totalBorrows,\n totalReserves,\n reserveFactorMantissa,\n badDebt\n );\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 borrowBalance The calculated balance\n */\n function borrowBalanceStored(address account) external view override returns (uint256) {\n return _borrowBalanceStored(account);\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 exchangeRate Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() external view override returns (uint256) {\n return _exchangeRateStored();\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return exchangeRate Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\n accrueInterest();\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.\n * @return Always NO_ERROR\n * @custom:event Emits AccrueInterest event on success\n * @custom:access Not restricted\n */\n function accrueInterest() public virtual override returns (uint256) {\n /* Remember the initial block number */\n uint256 currentBlockNumber = _getBlockNumber();\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\n\n /* Short-circuit accumulating 0 interest */\n if (accrualBlockNumberPrior == currentBlockNumber) {\n return NO_ERROR;\n }\n\n /* Read the previous values out of storage */\n uint256 cashPrior = _getCashPrior();\n uint256 borrowsPrior = totalBorrows;\n uint256 reservesPrior = totalReserves;\n uint256 borrowIndexPrior = borrowIndex;\n\n /* Calculate the current borrow interest rate */\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \"borrow rate is absurdly high\");\n\n /* Calculate the number of blocks elapsed since the last accrual */\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\n Exp({ mantissa: reserveFactorMantissa }),\n interestAccumulated,\n reservesPrior\n );\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\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 NO_ERROR;\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 payer The address of the account which is sending the assets for supply\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 */\n function _mintFresh(\n address payer,\n address minter,\n uint256 mintAmount\n ) internal {\n /* Fail if mint not allowed */\n comptroller.preMintHook(address(this), minter, mintAmount);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert MintFreshnessCheck();\n }\n\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\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 * And write them into storage\n */\n totalSupply = totalSupply + mintTokens;\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\n accountTokens[minter] = balanceAfter;\n\n /* We emit a Mint event, and a Transfer event */\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\n emit Transfer(address(0), minter, mintTokens);\n }\n\n /**\n * @notice User redeems vTokens in exchange for the underlying asset\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 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 */\n function _redeemFresh(\n address redeemer,\n uint256 redeemTokensIn,\n uint256 redeemAmountIn\n ) internal {\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \"one of redeemTokensIn or redeemAmountIn must be zero\");\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert RedeemFreshnessCheck();\n }\n\n /* exchangeRate = invoke Exchange Rate Stored() */\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\n\n uint256 redeemTokens;\n uint256 redeemAmount;\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 */\n redeemTokens = redeemTokensIn;\n } else {\n /*\n * We get the current exchange rate and calculate the amount to be redeemed:\n * redeemTokens = redeemAmountIn / exchangeRate\n */\n redeemTokens = div_(redeemAmountIn, exchangeRate);\n\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\n }\n\n // redeemAmount = exchangeRate * redeemTokens\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\n\n // Revert if amount is zero\n if (redeemAmount == 0) {\n revert(\"redeemAmount is zero\");\n }\n\n /* Fail if redeem not allowed */\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\n\n /* Fail gracefully if protocol has insufficient cash */\n if (_getCashPrior() - totalReserves < redeemAmount) {\n revert RedeemTransferOutNotPossible();\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We write the previously calculated values into storage.\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\n */\n totalSupply = totalSupply - redeemTokens;\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\n accountTokens[redeemer] = balanceAfter;\n\n /*\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\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 _doTransferOut(redeemer, redeemAmount);\n\n /* We emit a Transfer event, and a Redeem event */\n emit Transfer(redeemer, address(this), redeemTokens);\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\n }\n\n /**\n * @notice Users borrow assets from the protocol to their own address\n * @param borrower User who borrows the assets\n * @param borrowAmount The amount of the underlying asset to borrow\n */\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\n /* Fail if borrow not allowed */\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert BorrowFreshnessCheck();\n }\n\n /* Fail gracefully if protocol has insufficient underlying cash */\n if (_getCashPrior() - totalReserves < borrowAmount) {\n revert BorrowCashNotAvailable();\n }\n\n /*\n * We calculate the new borrower and total borrow balances, failing on overflow:\n * accountBorrowNew = accountBorrow + borrowAmount\n * totalBorrowsNew = totalBorrows + borrowAmount\n */\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We write the previously calculated values into storage.\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\n `*/\n accountBorrows[borrower].principal = accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n /*\n * We invoke _doTransferOut for the borrower and the borrowAmount.\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(borrower, borrowAmount);\n\n /* We emit a Borrow event */\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\n * @return (uint) the actual repayment amount.\n */\n function _repayBorrowFresh(\n address payer,\n address borrower,\n uint256 repayAmount\n ) internal returns (uint256) {\n /* Fail if repayBorrow not allowed */\n comptroller.preRepayHook(address(this), borrower);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert RepayBorrowFreshnessCheck();\n }\n\n /* We fetch the amount the borrower owes, with accumulated interest */\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\n\n /* We write the previously calculated values into storage */\n accountBorrows[borrower].principal = accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n /* We emit a RepayBorrow event */\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\n\n return actualRepayAmount;\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n */\n function _liquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) internal nonReentrant {\n accrueInterest();\n\n uint256 error = vTokenCollateral.accrueInterest();\n if (error != NO_ERROR) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n revert LiquidateAccrueCollateralInterestFailed(error);\n }\n\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\n }\n\n /**\n * @notice The liquidator liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n */\n function _liquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) internal {\n /* Fail if liquidate not allowed */\n comptroller.preLiquidateHook(\n address(this),\n address(vTokenCollateral),\n borrower,\n repayAmount,\n skipLiquidityCheck\n );\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert LiquidateFreshnessCheck();\n }\n\n /* Verify vTokenCollateral market's block number equals current block number */\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\n revert LiquidateCollateralFreshnessCheck();\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n revert LiquidateLiquidatorIsBorrower();\n }\n\n /* Fail if repayAmount = 0 */\n if (repayAmount == 0) {\n revert LiquidateCloseAmountIsZero();\n }\n\n /* Fail if repayAmount = type(uint256).max */\n if (repayAmount == type(uint256).max) {\n revert LiquidateCloseAmountIsUintMax();\n }\n\n /* Fail if repayBorrow fails */\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\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.liquidateCalculateSeizeTokens(\n address(this),\n address(vTokenCollateral),\n actualRepayAmount\n );\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\n if (address(vTokenCollateral) == address(this)) {\n _seize(address(this), liquidator, borrower, seizeTokens);\n } else {\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\n }\n\n /* We emit a LiquidateBorrow event */\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\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 */\n function _seize(\n address seizerContract,\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) internal {\n /* Fail if seize not allowed */\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n revert LiquidateSeizeLiquidatorIsBorrower();\n }\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\n .liquidationIncentiveMantissa();\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the calculated values into storage */\n totalReserves = totalReservesNew;\n totalSupply = totalSupply - protocolSeizeTokens;\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\n\n /* Emit a Transfer event */\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\n emit Transfer(borrower, address(this), protocolSeizeTokens);\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\n }\n\n function _setComptroller(ComptrollerInterface newComptroller) internal {\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\n /**\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\n * @dev Admin function to set a new reserve factor\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\n */\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\n // Verify market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert SetReserveFactorFreshCheck();\n }\n\n // Check newReserveFactor ≤ maxReserveFactor\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\n revert SetReserveFactorBoundsCheck();\n }\n\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\n reserveFactorMantissa = newReserveFactorMantissa;\n\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\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 actualAddAmount The actual amount added, excluding the potential token fees\n */\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\n // totalReserves + actualAddAmount\n uint256 totalReservesNew;\n uint256 actualAddAmount;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert AddReservesFactorFreshCheck(actualAddAmount);\n }\n\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\n totalReservesNew = totalReserves + actualAddAmount;\n totalReserves = totalReservesNew;\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\n\n return actualAddAmount;\n }\n\n /**\n * @notice Reduces reserves by transferring to the protocol reserve contract\n * @dev Requires fresh interest accrual\n * @param reduceAmount Amount of reduction to reserves\n */\n function _reduceReservesFresh(uint256 reduceAmount) internal {\n // totalReserves - reduceAmount\n uint256 totalReservesNew;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert ReduceReservesFreshCheck();\n }\n\n // Fail gracefully if protocol has insufficient underlying cash\n if (_getCashPrior() < reduceAmount) {\n revert ReduceReservesCashNotAvailable();\n }\n\n // Check reduceAmount ≤ reserves[n] (totalReserves)\n if (reduceAmount > totalReserves) {\n revert ReduceReservesCashValidation();\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\n _doTransferOut(protocolShareReserve, reduceAmount);\n\n // Update the pool asset's state in the protocol share reserve for the above transfer.\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\n\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\n }\n\n /**\n * @notice updates the interest rate model (*requires fresh interest accrual)\n * @dev Admin function to update the interest rate model\n * @param newInterestRateModel the new interest rate model to use\n */\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\n // Used to store old model for use in the event that is emitted on success\n InterestRateModel oldInterestRateModel;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert SetInterestRateModelFreshCheck();\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\n /*** Safe Token ***/\n\n /**\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\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 * @param from Sender of the underlying tokens\n * @param amount Amount of underlying to transfer\n * @return Actual amount received\n */\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n uint256 balanceBefore = token.balanceOf(address(this));\n token.safeTransferFrom(from, address(this), amount);\n uint256 balanceAfter = token.balanceOf(address(this));\n // Return the amount that was *actually* transferred\n return balanceAfter - balanceBefore;\n }\n\n /**\n * @dev Just a regular ERC-20 transfer, reverts on failure\n * @param to Receiver of the underlying tokens\n * @param amount Amount of underlying to transfer\n */\n function _doTransferOut(address to, uint256 amount) internal virtual {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n token.safeTransfer(to, amount);\n }\n\n /**\n * @notice Transfer `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 */\n function _transferTokens(\n address spender,\n address src,\n address dst,\n uint256 tokens\n ) internal {\n /* Fail if transfer not allowed */\n comptroller.preTransferHook(address(this), src, dst, tokens);\n\n /* Do not allow self-transfers */\n if (src == dst) {\n revert TransferNotAllowed();\n }\n\n /* Get the allowance, infinite for the account owner */\n uint256 startingAllowance;\n if (spender == src) {\n startingAllowance = type(uint256).max;\n } else {\n startingAllowance = transferAllowances[src][spender];\n }\n\n /* Do the calculations, checking for {under,over}flow */\n uint256 allowanceNew = startingAllowance - tokens;\n uint256 srcTokensNew = accountTokens[src] - tokens;\n uint256 dstTokensNew = accountTokens[dst] + tokens;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n\n accountTokens[src] = srcTokensNew;\n accountTokens[dst] = dstTokensNew;\n\n /* Eat some of the allowance (if necessary) */\n if (startingAllowance != type(uint256).max) {\n transferAllowances[src][spender] = allowanceNew;\n }\n\n /* We emit a Transfer event */\n emit Transfer(src, dst, tokens);\n }\n\n /**\n * @notice Initialize the 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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param accessControlManager_ AccessControlManager contract address\n * @param riskManagement Addresses of risk & income related contracts\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\n */\n function _initialize(\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 admin_,\n address accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) internal onlyInitializing {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\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 _setComptroller(comptroller_);\n\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\n accrualBlockNumber = _getBlockNumber();\n borrowIndex = MANTISSA_ONE;\n\n // Set the interest rate model (depends on block number / borrow index)\n _setInterestRateModelFresh(interestRateModel_);\n\n _setReserveFactorFresh(reserveFactorMantissa_);\n\n name = name_;\n symbol = symbol_;\n decimals = decimals_;\n _setShortfallContract(riskManagement.shortfall);\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\n\n // Set underlying and sanity check it\n underlying = underlying_;\n IERC20Upgradeable(underlying).totalSupply();\n\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\n _notEntered = true;\n _transferOwnership(admin_);\n }\n\n function _setShortfallContract(address shortfall_) internal {\n ensureNonzeroAddress(shortfall_);\n address oldShortfall = shortfall;\n shortfall = shortfall_;\n emit NewShortfallContract(oldShortfall, shortfall_);\n }\n\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\n ensureNonzeroAddress(protocolShareReserve_);\n address oldProtocolShareReserve = address(protocolShareReserve);\n protocolShareReserve = protocolShareReserve_;\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\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 virtual returns (uint256) {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n return token.balanceOf(address(this));\n }\n\n /**\n * @dev Function to simply retrieve block number\n * This exists mainly for inheriting test contracts to stub this result.\n * @return Current block number\n */\n function _getBlockNumber() internal view virtual returns (uint256) {\n return block.number;\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 borrowBalance the calculated balance\n */\n function _borrowBalanceStored(address account) internal view returns (uint256) {\n /* Get borrowBalance and borrowIndex */\n BorrowSnapshot memory 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 0;\n }\n\n /* Calculate new borrow balance using the interest index:\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\n */\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\n\n return principalTimesIndex / borrowSnapshot.interestIndex;\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 exchangeRate Calculated exchange rate scaled by 1e18\n */\n function _exchangeRateStored() internal view virtual returns (uint256) {\n uint256 _totalSupply = totalSupply;\n if (_totalSupply == 0) {\n /*\n * If there are no tokens minted:\n * exchangeRate = initialExchangeRate\n */\n return initialExchangeRateMantissa;\n }\n /*\n * Otherwise:\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\n */\n uint256 totalCash = _getCashPrior();\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\n\n return exchangeRate;\n }\n}\n" + }, + "contracts/VTokenInterfaces.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { ComptrollerInterface } from \"./ComptrollerInterface.sol\";\nimport { InterestRateModel } from \"./InterestRateModel.sol\";\n\n/**\n * @title VTokenStorage\n * @author Venus\n * @notice Storage layout used by the `VToken` contract\n */\n// solhint-disable-next-line max-states-count\ncontract VTokenStorage {\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 uint256 principal;\n uint256 interestIndex;\n }\n\n /**\n * @dev Guard variable for re-entrancy checks\n */\n bool internal _notEntered;\n\n /**\n * @notice Underlying asset for this VToken\n */\n address public underlying;\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 Protocol share Reserve contract address\n */\n address payable public protocolShareReserve;\n\n // Maximum borrow rate that can ever be applied (.0005% / block)\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\n\n // Maximum fraction of interest that can be set aside for reserves\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\n uint256 internal initialExchangeRateMantissa;\n\n /**\n * @notice Fraction of interest currently set aside for reserves\n */\n uint256 public reserveFactorMantissa;\n\n /**\n * @notice Block number that interest was last accrued at\n */\n uint256 public accrualBlockNumber;\n\n /**\n * @notice Accumulator of the total earned interest rate since the opening of the market\n */\n uint256 public borrowIndex;\n\n /**\n * @notice Total amount of outstanding borrows of the underlying in this market\n */\n uint256 public totalBorrows;\n\n /**\n * @notice Total amount of reserves of the underlying held in this market\n */\n uint256 public totalReserves;\n\n /**\n * @notice Total number of tokens in circulation\n */\n uint256 public totalSupply;\n\n /**\n * @notice Total bad debt of the market\n */\n uint256 public badDebt;\n\n // Official record of token balances for each account\n mapping(address => uint256) internal accountTokens;\n\n // Approved token transfer amounts on behalf of others\n mapping(address => mapping(address => uint256)) internal transferAllowances;\n\n // Mapping of account addresses to outstanding borrow balances\n mapping(address => BorrowSnapshot) internal accountBorrows;\n\n /**\n * @notice Share of seized collateral that is added to reserves\n */\n uint256 public protocolSeizeShareMantissa;\n\n /**\n * @notice Storage of Shortfall contract address\n */\n address public shortfall;\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[50] private __gap;\n}\n\n/**\n * @title VTokenInterface\n * @author Venus\n * @notice Interface implemented by the `VToken` contract\n */\nabstract contract VTokenInterface is VTokenStorage {\n struct RiskManagementInit {\n address shortfall;\n address payable protocolShareReserve;\n }\n\n /*** Market Events ***/\n\n /**\n * @notice Event emitted when interest is accrued\n */\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\n\n /**\n * @notice Event emitted when tokens are minted\n */\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\n\n /**\n * @notice Event emitted when tokens are redeemed\n */\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\n\n /**\n * @notice Event emitted when underlying is borrowed\n */\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\n\n /**\n * @notice Event emitted when a borrow is repaid\n */\n event RepayBorrow(\n address indexed payer,\n address indexed borrower,\n uint256 repayAmount,\n uint256 accountBorrows,\n uint256 totalBorrows\n );\n\n /**\n * @notice Event emitted when bad debt is accumulated on a market\n * @param borrower borrower to \"forgive\"\n * @param badDebtDelta amount of new bad debt recorded\n * @param badDebtOld previous bad debt value\n * @param badDebtNew new bad debt value\n */\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\n\n /**\n * @notice Event emitted when bad debt is recovered via an auction\n * @param badDebtOld previous bad debt value\n * @param badDebtNew new bad debt value\n */\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\n\n /**\n * @notice Event emitted when a borrow is liquidated\n */\n event LiquidateBorrow(\n address indexed liquidator,\n address indexed borrower,\n uint256 repayAmount,\n address indexed vTokenCollateral,\n uint256 seizeTokens\n );\n\n /*** Admin Events ***/\n\n /**\n * @notice Event emitted when comptroller is changed\n */\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\n\n /**\n * @notice Event emitted when shortfall contract address is changed\n */\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\n\n /**\n * @notice Event emitted when protocol share reserve contract address is changed\n */\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\n\n /**\n * @notice Event emitted when interestRateModel is changed\n */\n event NewMarketInterestRateModel(\n InterestRateModel indexed oldInterestRateModel,\n InterestRateModel indexed newInterestRateModel\n );\n\n /**\n * @notice Event emitted when protocol seize share is changed\n */\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\n\n /**\n * @notice Event emitted when the reserve factor is changed\n */\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\n\n /**\n * @notice Event emitted when the reserves are added\n */\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\n\n /**\n * @notice Event emitted when the reserves are reduced\n */\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\n\n /**\n * @notice EIP20 Transfer event\n */\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /**\n * @notice EIP20 Approval event\n */\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Event emitted when healing the borrow\n */\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\n\n /**\n * @notice Event emitted when tokens are swept\n */\n event SweepToken(address indexed token);\n\n /*** User Interface ***/\n\n function mint(uint256 mintAmount) external virtual returns (uint256);\n\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\n\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\n\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\n\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\n\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\n\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\n\n function liquidateBorrow(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external virtual returns (uint256);\n\n function healBorrow(\n address payer,\n address borrower,\n uint256 repayAmount\n ) external virtual;\n\n function forceLiquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipCloseFactorCheck\n ) external virtual;\n\n function seize(\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external virtual;\n\n function transfer(address dst, uint256 amount) external virtual returns (bool);\n\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) external virtual returns (bool);\n\n function accrueInterest() external virtual returns (uint256);\n\n function sweepToken(IERC20Upgradeable token) external virtual;\n\n /*** Admin Functions ***/\n\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\n\n function reduceReserves(uint256 reduceAmount) external virtual;\n\n function exchangeRateCurrent() external virtual returns (uint256);\n\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\n\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\n\n function addReserves(uint256 addAmount) external virtual;\n\n function totalBorrowsCurrent() external virtual returns (uint256);\n\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\n\n function approve(address spender, uint256 amount) external virtual returns (bool);\n\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\n\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\n\n function allowance(address owner, address spender) external view virtual returns (uint256);\n\n function balanceOf(address owner) external view virtual returns (uint256);\n\n function getAccountSnapshot(address account)\n external\n view\n virtual\n returns (\n uint256,\n uint256,\n uint256,\n uint256\n );\n\n function borrowRatePerBlock() external view virtual returns (uint256);\n\n function supplyRatePerBlock() external view virtual returns (uint256);\n\n function borrowBalanceStored(address account) external view virtual returns (uint256);\n\n function exchangeRateStored() external view virtual returns (uint256);\n\n function getCash() external view virtual returns (uint256);\n\n /**\n * @notice Indicator that this is a VToken contract (for inspection)\n * @return Always true\n */\n function isVToken() external pure virtual returns (bool) {\n return true;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "yul": true + } + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/bsctestnet.json b/deployments/bsctestnet.json index b41b3c6a4..fb97820ff 100644 --- a/deployments/bsctestnet.json +++ b/deployments/bsctestnet.json @@ -110,7 +110,7 @@ ] }, "ComptrollerImpl": { - "address": "0x80691DaD6dAb8a028FFE68bb8045f2547d210f9D", + "address": "0x069705246364d60c5503bF19b4A714ab412521a0", "abi": [ { "inputs": [ @@ -11633,143 +11633,160 @@ } ] }, - "RewardsDistributorImpl": { - "address": "0xfAE44cf6309598c2557Bb265BF0401D594db97DA", + "ProtocolShareReserve": { + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", "abi": [ { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "loopsLimit", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" }, { - "internalType": "uint256", - "name": "requiredLoops", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "name": "MaxLoopsLimitExceeded", - "type": "error" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "sender", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "calledContract", + "name": "implementation", "type": "address" - }, + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "internalType": "address", + "name": "admin_", + "type": "address" } ], - "name": "Unauthorized", - "type": "error" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "vToken", + "name": "newAdmin", "type": "address" - }, + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ { - "indexed": false, - "internalType": "uint32", - "name": "newBlock", - "type": "uint32" + "internalType": "address", + "name": "implementation_", + "type": "address" } ], - "name": "BorrowLastRewardingBlockUpdated", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "contributor", + "name": "newImplementation", "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newSpeed", - "type": "uint256" } ], - "name": "ContributorRewardTokenSpeedUpdated", - "type": "event" + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "contributor", + "name": "newImplementation", "type": "address" }, { - "indexed": false, - "internalType": "uint256", - "name": "rewardAccrued", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "ContributorRewardsUpdated", - "type": "event" + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, - "internalType": "contract VToken", - "name": "vToken", + "internalType": "address", + "name": "comptroller", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "borrower", + "name": "asset", "type": "address" }, { "indexed": false, "internalType": "uint256", - "name": "rewardTokenDelta", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewardTokenTotal", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewardTokenBorrowIndex", + "name": "amount", "type": "uint256" } ], - "name": "DistributedBorrowerRewardToken", + "name": "AssetsReservesUpdated", "type": "event" }, { @@ -11777,36 +11794,24 @@ "inputs": [ { "indexed": true, - "internalType": "contract VToken", - "name": "vToken", + "internalType": "address", + "name": "comptroller", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "supplier", + "name": "asset", "type": "address" }, { "indexed": false, "internalType": "uint256", - "name": "rewardTokenDelta", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewardTokenTotal", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewardTokenSupplyIndex", + "name": "amount", "type": "uint256" } ], - "name": "DistributedSupplierRewardToken", + "name": "FundsReleased", "type": "event" }, { @@ -11828,49 +11833,17 @@ { "indexed": true, "internalType": "address", - "name": "vToken", - "type": "address" - } - ], - "name": "MarketInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldMaxLoopsLimit", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newmaxLoopsLimit", - "type": "uint256" - } - ], - "name": "MaxLoopsLimitUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "oldAccessControlManager", + "name": "previousOwner", "type": "address" }, { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "newAccessControlManager", + "name": "newOwner", "type": "address" } ], - "name": "NewAccessControlManager", + "name": "OwnershipTransferStarted", "type": "event" }, { @@ -11889,7 +11862,7 @@ "type": "address" } ], - "name": "OwnershipTransferStarted", + "name": "OwnershipTransferred", "type": "event" }, { @@ -11898,17 +11871,17 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "oldPoolRegistry", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "newPoolRegistry", "type": "address" } ], - "name": "OwnershipTransferred", + "name": "PoolRegistryUpdated", "type": "event" }, { @@ -11917,123 +11890,101 @@ { "indexed": true, "internalType": "address", - "name": "vToken", + "name": "token", "type": "address" }, - { - "components": [ - { - "internalType": "uint256", - "name": "mantissa", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ExponentialNoError.Exp", - "name": "marketBorrowIndex", - "type": "tuple" - } - ], - "name": "RewardTokenBorrowIndexUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ { "indexed": true, - "internalType": "contract VToken", - "name": "vToken", + "internalType": "address", + "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", - "name": "newSpeed", + "name": "amount", "type": "uint256" } ], - "name": "RewardTokenBorrowSpeedUpdated", + "name": "SweepToken", "type": "event" }, { - "anonymous": false, + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [ { - "indexed": true, "internalType": "address", - "name": "recipient", + "name": "", "type": "address" - }, + } + ], + "name": "assetsReserves", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "amount", + "name": "", "type": "uint256" } ], - "name": "RewardTokenGranted", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "vToken", + "name": "comptroller", "type": "address" - } - ], - "name": "RewardTokenSupplyIndexUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, - "internalType": "contract VToken", - "name": "vToken", + "internalType": "address", + "name": "asset", "type": "address" - }, + } + ], + "name": "getPoolAssetReserve", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "newSpeed", + "name": "", "type": "uint256" } ], - "name": "RewardTokenSupplySpeedUpdated", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "vToken", + "name": "protocolIncome_", "type": "address" }, { - "indexed": false, - "internalType": "uint32", - "name": "newBlock", - "type": "uint32" + "internalType": "address", + "name": "riskFund_", + "type": "address" } ], - "name": "SupplyLastRewardingBlockUpdated", - "type": "event" + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "INITIAL_INDEX", + "name": "owner", "outputs": [ { - "internalType": "uint224", + "internalType": "address", "name": "", - "type": "uint224" + "type": "address" } ], "stateMutability": "view", @@ -12041,17 +11992,10 @@ }, { "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "accessControlManager", + "name": "pendingOwner", "outputs": [ { - "internalType": "contract IAccessControlManagerV8", + "internalType": "address", "name": "", "type": "address" } @@ -12060,92 +12004,75 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "poolRegistry", + "outputs": [ { "internalType": "address", - "name": "holder", + "name": "", "type": "address" - }, - { - "internalType": "contract VToken[]", - "name": "vTokens", - "type": "address[]" } ], - "name": "claimRewardToken", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "protocolIncome", + "outputs": [ { "internalType": "address", - "name": "holder", + "name": "", "type": "address" } ], - "name": "claimRewardToken", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "comptroller", "type": "address" }, { "internalType": "address", - "name": "borrower", + "name": "asset", "type": "address" }, { - "components": [ - { - "internalType": "uint256", - "name": "mantissa", - "type": "uint256" - } - ], - "internalType": "struct ExponentialNoError.Exp", - "name": "marketBorrowIndex", - "type": "tuple" + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "releaseFunds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "distributeBorrowerRewardToken", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "vToken", - "type": "address" - }, - { - "internalType": "address", - "name": "supplier", - "type": "address" - } - ], - "name": "distributeSupplierRewardToken", + "inputs": [], + "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "getBlockNumber", + "name": "riskFund", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", @@ -12155,16 +12082,11 @@ "inputs": [ { "internalType": "address", - "name": "recipient", + "name": "poolRegistry_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" } ], - "name": "grantRewardToken", + "name": "setPoolRegistry", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -12172,27 +12094,17 @@ { "inputs": [ { - "internalType": "contract Comptroller", - "name": "comptroller_", - "type": "address" - }, - { - "internalType": "contract IERC20Upgradeable", - "name": "rewardToken_", + "internalType": "address", + "name": "_token", "type": "address" }, - { - "internalType": "uint256", - "name": "loopsLimit_", - "type": "uint256" - }, { "internalType": "address", - "name": "accessControlManager_", + "name": "_to", "type": "address" } ], - "name": "initialize", + "name": "sweepToken", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -12201,11 +12113,11 @@ "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "newOwner", "type": "address" } ], - "name": "initializeMarket", + "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -12214,169 +12126,206 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" - } - ], - "name": "lastContributorBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxLoopsLimit", - "outputs": [ + }, { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "address", + "name": "asset", + "type": "address" } ], - "stateMutability": "view", + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "_logic", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + }, { "internalType": "address", - "name": "", + "name": "admin_", "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" - }, + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "ProtocolShareReserve_Implementation": { + "address": "0x0Bbea4B14f475bF5eb60Fc2b0Ca90d3d089Ef833", + "abi": [ { "inputs": [], - "name": "renounceOwnership", - "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "constructor" }, { "inputs": [], - "name": "rewardToken", - "outputs": [ - { - "internalType": "contract IERC20Upgradeable", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "name": "ZeroAddressNotAllowed", + "type": "error" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" - } - ], - "name": "rewardTokenAccrued", - "outputs": [ + }, { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "amount", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "AssetsReservesUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" - } - ], - "name": "rewardTokenBorrowSpeeds", - "outputs": [ + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "amount", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "FundsReleased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", "type": "address" } ], - "name": "rewardTokenBorrowState", - "outputs": [ - { - "internalType": "uint224", - "name": "index", - "type": "uint224" - }, + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint32", - "name": "block", - "type": "uint32" + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" }, { - "internalType": "uint32", - "name": "lastRewardingBlock", - "type": "uint32" + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "OwnershipTransferred", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "oldPoolRegistry", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "", + "name": "newPoolRegistry", "type": "address" } ], - "name": "rewardTokenBorrowerIndex", - "outputs": [ + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "amount", "type": "uint256" } ], - "stateMutability": "view", + "name": "SweepToken", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { @@ -12387,7 +12336,7 @@ "type": "address" } ], - "name": "rewardTokenContributorSpeeds", + "name": "assetsReserves", "outputs": [ { "internalType": "uint256", @@ -12402,16 +12351,16 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" }, { "internalType": "address", - "name": "", + "name": "asset", "type": "address" } ], - "name": "rewardTokenSupplierIndex", + "name": "getPoolAssetReserve", "outputs": [ { "internalType": "uint256", @@ -12426,149 +12375,130 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "protocolIncome_", + "type": "address" + }, + { + "internalType": "address", + "name": "riskFund_", "type": "address" } ], - "name": "rewardTokenSupplySpeeds", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "pendingOwner", + "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], - "name": "rewardTokenSupplyState", - "outputs": [ - { - "internalType": "uint224", - "name": "index", - "type": "uint224" - }, - { - "internalType": "uint32", - "name": "block", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "lastRewardingBlock", - "type": "uint32" - } - ], "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "poolRegistry", + "outputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "", "type": "address" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "protocolIncome", + "outputs": [ { "internalType": "address", - "name": "contributor", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "rewardTokenSpeed", - "type": "uint256" } ], - "name": "setContributorRewardTokenSpeed", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { - "internalType": "contract VToken[]", - "name": "vTokens", - "type": "address[]" + "internalType": "address", + "name": "comptroller", + "type": "address" }, { - "internalType": "uint32[]", - "name": "supplyLastRewardingBlocks", - "type": "uint32[]" + "internalType": "address", + "name": "asset", + "type": "address" }, { - "internalType": "uint32[]", - "name": "borrowLastRewardingBlocks", - "type": "uint32[]" + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "setLastRewardingBlocks", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "name": "releaseFunds", + "outputs": [ { "internalType": "uint256", - "name": "limit", + "name": "", "type": "uint256" } ], - "name": "setMaxLoopsLimit", + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "contract VToken[]", - "name": "vTokens", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "supplySpeeds", - "type": "uint256[]" - }, + "inputs": [], + "name": "riskFund", + "outputs": [ { - "internalType": "uint256[]", - "name": "borrowSpeeds", - "type": "uint256[]" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "setRewardTokenSpeeds", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "newOwner", + "name": "poolRegistry_", "type": "address" } ], - "name": "transferOwnership", + "name": "setPoolRegistry", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -12577,11 +12507,16 @@ "inputs": [ { "internalType": "address", - "name": "contributor", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", "type": "address" } ], - "name": "updateContributorRewards", + "name": "sweepToken", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -12590,23 +12525,11 @@ "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "newOwner", "type": "address" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "mantissa", - "type": "uint256" - } - ], - "internalType": "struct ExponentialNoError.Exp", - "name": "marketBorrowIndex", - "type": "tuple" } ], - "name": "updateRewardTokenBorrowIndex", + "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -12615,20 +12538,46 @@ "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", "type": "address" } ], - "name": "updateRewardTokenSupplyIndex", + "name": "updateAssetsState", "outputs": [], "stateMutability": "nonpayable", "type": "function" } ] }, - "RewardsDistributor_DeFi_0": { - "address": "0x2b67Cfaf28a1aBbBf71fb814Ad384d0C5a98e0F9", + "ProtocolShareReserve_Proxy": { + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, { "anonymous": false, "inputs": [ @@ -12751,6 +12700,16 @@ { "stateMutability": "payable", "type": "receive" + } + ] + }, + "RewardsDistributorImpl": { + "address": "0xfAE44cf6309598c2557Bb265BF0401D594db97DA", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" }, { "inputs": [ @@ -13734,181 +13693,11 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" } ] }, - "RewardsDistributor_DeFi_0_Proxy": { + "RewardsDistributor_DeFi_0": { "address": "0x2b67Cfaf28a1aBbBf71fb814Ad384d0C5a98e0F9", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "admin_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "implementation_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "RewardsDistributor_DeFi_1": { - "address": "0x4be90041D1e082EfE3613099aA3b987D9045d718", "abi": [ { "anonymous": false, @@ -15039,8 +14828,8 @@ } ] }, - "RewardsDistributor_DeFi_1_Proxy": { - "address": "0x4be90041D1e082EfE3613099aA3b987D9045d718", + "RewardsDistributor_DeFi_0_Proxy": { + "address": "0x2b67Cfaf28a1aBbBf71fb814Ad384d0C5a98e0F9", "abi": [ { "inputs": [ @@ -15188,8 +14977,8 @@ } ] }, - "RewardsDistributor_GameFi_0": { - "address": "0x5651866bcC4650d6fe5178E5ED7a8Be2cf3F70D0", + "RewardsDistributor_DeFi_1": { + "address": "0x4be90041D1e082EfE3613099aA3b987D9045d718", "abi": [ { "anonymous": false, @@ -16320,8 +16109,8 @@ } ] }, - "RewardsDistributor_GameFi_0_Proxy": { - "address": "0x5651866bcC4650d6fe5178E5ED7a8Be2cf3F70D0", + "RewardsDistributor_DeFi_1_Proxy": { + "address": "0x4be90041D1e082EfE3613099aA3b987D9045d718", "abi": [ { "inputs": [ @@ -16469,8 +16258,8 @@ } ] }, - "RewardsDistributor_GameFi_1": { - "address": "0x66E213a4b8ba1c8D62cAa4649C7177E29321E262", + "RewardsDistributor_GameFi_0": { + "address": "0x5651866bcC4650d6fe5178E5ED7a8Be2cf3F70D0", "abi": [ { "anonymous": false, @@ -17601,8 +17390,8 @@ } ] }, - "RewardsDistributor_GameFi_1_Proxy": { - "address": "0x66E213a4b8ba1c8D62cAa4649C7177E29321E262", + "RewardsDistributor_GameFi_0_Proxy": { + "address": "0x5651866bcC4650d6fe5178E5ED7a8Be2cf3F70D0", "abi": [ { "inputs": [ @@ -17750,8 +17539,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_0": { - "address": "0x7df11563c6b6b8027aE619FD9644A647dED5893B", + "RewardsDistributor_GameFi_1": { + "address": "0x66E213a4b8ba1c8D62cAa4649C7177E29321E262", "abi": [ { "anonymous": false, @@ -18882,8 +18671,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_0_Proxy": { - "address": "0x7df11563c6b6b8027aE619FD9644A647dED5893B", + "RewardsDistributor_GameFi_1_Proxy": { + "address": "0x66E213a4b8ba1c8D62cAa4649C7177E29321E262", "abi": [ { "inputs": [ @@ -19031,8 +18820,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_1": { - "address": "0x72c770A1E73Ad9ccD5249fC5536346f95345Fe2c", + "RewardsDistributor_LiquidStakedBNB_0": { + "address": "0x7df11563c6b6b8027aE619FD9644A647dED5893B", "abi": [ { "anonymous": false, @@ -20163,8 +19952,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_1_Proxy": { - "address": "0x72c770A1E73Ad9ccD5249fC5536346f95345Fe2c", + "RewardsDistributor_LiquidStakedBNB_0_Proxy": { + "address": "0x7df11563c6b6b8027aE619FD9644A647dED5893B", "abi": [ { "inputs": [ @@ -20312,8 +20101,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_2": { - "address": "0x8Ad2Ad29e4e2C0606644Be51c853A7A4a3078F85", + "RewardsDistributor_LiquidStakedBNB_1": { + "address": "0x72c770A1E73Ad9ccD5249fC5536346f95345Fe2c", "abi": [ { "anonymous": false, @@ -21444,8 +21233,8 @@ } ] }, - "RewardsDistributor_LiquidStakedBNB_2_Proxy": { - "address": "0x8Ad2Ad29e4e2C0606644Be51c853A7A4a3078F85", + "RewardsDistributor_LiquidStakedBNB_1_Proxy": { + "address": "0x72c770A1E73Ad9ccD5249fC5536346f95345Fe2c", "abi": [ { "inputs": [ @@ -21593,8 +21382,8 @@ } ] }, - "RewardsDistributor_StableCoins_0": { - "address": "0xb0269d68CfdCc30Cb7Cd2E0b52b08Fa7Ffd3079b", + "RewardsDistributor_LiquidStakedBNB_2": { + "address": "0x8Ad2Ad29e4e2C0606644Be51c853A7A4a3078F85", "abi": [ { "anonymous": false, @@ -22725,8 +22514,8 @@ } ] }, - "RewardsDistributor_StableCoins_0_Proxy": { - "address": "0xb0269d68CfdCc30Cb7Cd2E0b52b08Fa7Ffd3079b", + "RewardsDistributor_LiquidStakedBNB_2_Proxy": { + "address": "0x8Ad2Ad29e4e2C0606644Be51c853A7A4a3078F85", "abi": [ { "inputs": [ @@ -22874,8 +22663,8 @@ } ] }, - "RewardsDistributor_StableCoins_1": { - "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "RewardsDistributor_LiquidStakedBNB_3": { + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", "abi": [ { "anonymous": false, @@ -24006,8 +23795,8 @@ } ] }, - "RewardsDistributor_StableCoins_1_Proxy": { - "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", + "RewardsDistributor_LiquidStakedBNB_3_Proxy": { + "address": "0x37fA1e5613455223F09e179DFAEBba61d7505C97", "abi": [ { "inputs": [ @@ -24155,8 +23944,8 @@ } ] }, - "RewardsDistributor_Tron_0": { - "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", + "RewardsDistributor_StableCoins_0": { + "address": "0xb0269d68CfdCc30Cb7Cd2E0b52b08Fa7Ffd3079b", "abi": [ { "anonymous": false, @@ -25287,8 +25076,8 @@ } ] }, - "RewardsDistributor_Tron_0_Proxy": { - "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", + "RewardsDistributor_StableCoins_0_Proxy": { + "address": "0xb0269d68CfdCc30Cb7Cd2E0b52b08Fa7Ffd3079b", "abi": [ { "inputs": [ @@ -25436,8 +25225,8 @@ } ] }, - "RewardsDistributor_Tron_1": { - "address": "0x9A73Ba89f6a95611B46b68241aBEcAF2cD0bd78A", + "RewardsDistributor_StableCoins_1": { + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "abi": [ { "anonymous": false, @@ -26568,8 +26357,8 @@ } ] }, - "RewardsDistributor_Tron_1_Proxy": { - "address": "0x9A73Ba89f6a95611B46b68241aBEcAF2cD0bd78A", + "RewardsDistributor_StableCoins_1_Proxy": { + "address": "0x2aBEf3602B688493fe698EF11D27DCa43a0CE4BE", "abi": [ { "inputs": [ @@ -26717,8 +26506,8 @@ } ] }, - "RewardsDistributor_Tron_2": { - "address": "0x507401883C2a874D919e78a73dD0cB56f2e7eaD7", + "RewardsDistributor_Tron_0": { + "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", "abi": [ { "anonymous": false, @@ -27849,8 +27638,8 @@ } ] }, - "RewardsDistributor_Tron_2_Proxy": { - "address": "0x507401883C2a874D919e78a73dD0cB56f2e7eaD7", + "RewardsDistributor_Tron_0_Proxy": { + "address": "0x095902273F06eEAC825c3F52dEF44f67a86B31cD", "abi": [ { "inputs": [ @@ -27998,8 +27787,8 @@ } ] }, - "RewardsDistributor_Tron_3": { - "address": "0x1c50672f4752cc0Ae532D9b93b936C21121Ff08b", + "RewardsDistributor_Tron_1": { + "address": "0x9A73Ba89f6a95611B46b68241aBEcAF2cD0bd78A", "abi": [ { "anonymous": false, @@ -29130,8 +28919,8 @@ } ] }, - "RewardsDistributor_Tron_3_Proxy": { - "address": "0x1c50672f4752cc0Ae532D9b93b936C21121Ff08b", + "RewardsDistributor_Tron_1_Proxy": { + "address": "0x9A73Ba89f6a95611B46b68241aBEcAF2cD0bd78A", "abi": [ { "inputs": [ @@ -29279,302 +29068,362 @@ } ] }, - "SwapRouter_DeFi": { - "address": "0x89Bc8dFe0Af08b60ec285071d133FCdfa9B3C08e", + "RewardsDistributor_Tron_2": { + "address": "0x507401883C2a874D919e78a73dD0cB56f2e7eaD7", "abi": [ { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "WBNB_", + "name": "previousAdmin", "type": "address" }, { + "indexed": false, "internalType": "address", - "name": "factory_", + "name": "newAdmin", "type": "address" - }, + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "_comptrollerAddress", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "_vBNBAddress", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", "type": "address" } ], "stateMutability": "nonpayable", - "type": "constructor" + "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountMax", - "type": "uint256" + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "name": "ExcessiveInputAmount", - "type": "error" + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "IdenticalAddresses", - "type": "error" + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountIntMax", - "type": "uint256" + "internalType": "address", + "name": "newImplementation", + "type": "address" } ], - "name": "InputAmountAboveMaximum", - "type": "error" + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "sweepAmount", - "type": "uint256" + "internalType": "address", + "name": "newImplementation", + "type": "address" }, { - "internalType": "uint256", - "name": "balance", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "InsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientInputAmount", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientLiquidity", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientOutputAmount", - "type": "error" + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "inputs": [], - "name": "InvalidPath", - "type": "error" + "stateMutability": "payable", + "type": "receive" }, { "inputs": [ { "internalType": "uint256", - "name": "amountOut", + "name": "loopsLimit", "type": "uint256" }, { "internalType": "uint256", - "name": "amountOutMin", + "name": "requiredLoops", "type": "uint256" } ], - "name": "OutputAmountBelowMinimum", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrantCheck", + "name": "MaxLoopsLimitExceeded", "type": "error" }, { "inputs": [ { "internalType": "address", - "name": "repayer", + "name": "sender", "type": "address" }, { "internalType": "address", - "name": "vToken", + "name": "calledContract", "type": "address" }, { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" + "internalType": "string", + "name": "methodSignature", + "type": "string" } ], - "name": "RepayError", - "type": "error" - }, - { - "inputs": [], - "name": "SafeApproveFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferBNBFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferFromFailed", + "name": "Unauthorized", "type": "error" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "supplier", + "name": "vToken", "type": "address" }, { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, "internalType": "address", - "name": "vToken", + "name": "contributor", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "errorCode", + "name": "newSpeed", "type": "uint256" } ], - "name": "SupplyError", - "type": "error" + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOutMin", + "name": "rewardAccrued", "type": "uint256" } ], - "name": "SwapAmountLessThanAmountOutMin", - "type": "error" + "name": "ContributorRewardsUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "timestemp", + "name": "rewardTokenBorrowIndex", "type": "uint256" } ], - "name": "SwapDeadlineExpire", - "type": "error" + "name": "DistributedBorrowerRewardToken", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "address", + "indexed": true, + "internalType": "contract VToken", "name": "vToken", "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" } ], - "name": "VTokenNotListed", - "type": "error" + "name": "DistributedSupplierRewardToken", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "address", - "name": "underlying", - "type": "address" + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" } ], - "name": "VTokenUnderlyingInvalid", - "type": "error" + "name": "Initialized", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "expectedAdddress", - "type": "address" - }, - { - "internalType": "address", - "name": "passedAddress", + "name": "vToken", "type": "address" } ], - "name": "WrongAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" + "name": "MarketInitialized", + "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" } ], - "name": "OwnershipTransferStarted", + "name": "MaxLoopsLimitUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "previousOwner", + "name": "oldAccessControlManager", "type": "address" }, { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "newOwner", + "name": "newAccessControlManager", "type": "address" } ], - "name": "OwnershipTransferred", + "name": "NewAccessControlManager", "type": "event" }, { @@ -29583,23 +29432,17 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "previousOwner", "type": "address" }, { "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "SwapBnbForTokens", + "name": "OwnershipTransferStarted", "type": "event" }, { @@ -29608,17 +29451,17 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "previousOwner", "type": "address" }, { "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "SwapBnbForTokensAtSupportingFee", + "name": "OwnershipTransferred", "type": "event" }, { @@ -29627,23 +29470,24 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "vToken", "type": "address" }, { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" } ], - "name": "SwapTokensForBnb", + "name": "RewardTokenBorrowIndexUpdated", "type": "event" }, { @@ -29651,18 +29495,18 @@ "inputs": [ { "indexed": true, - "internalType": "address", - "name": "swapper", + "internalType": "contract VToken", + "name": "vToken", "type": "address" }, { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" } ], - "name": "SwapTokensForBnbAtSupportingFee", + "name": "RewardTokenBorrowSpeedUpdated", "type": "event" }, { @@ -29671,23 +29515,17 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "recipient", "type": "address" }, { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "SwapTokensForTokens", + "name": "RewardTokenGranted", "type": "event" }, { @@ -29696,17 +29534,11 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "vToken", "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" } ], - "name": "SwapTokensForTokensAtSupportingFee", + "name": "RewardTokenSupplyIndexUpdated", "type": "event" }, { @@ -29714,24 +29546,18 @@ "inputs": [ { "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", + "internalType": "contract VToken", + "name": "vToken", "type": "address" }, { "indexed": false, "internalType": "uint256", - "name": "sweepAmount", + "name": "newSpeed", "type": "uint256" } ], - "name": "SweepToken", + "name": "RewardTokenSupplySpeedUpdated", "type": "event" }, { @@ -29740,27 +29566,27 @@ { "indexed": true, "internalType": "address", - "name": "oldAddress", + "name": "vToken", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "newAddress", - "type": "address" + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" } ], - "name": "VBNBAddressUpdated", + "name": "SupplyLastRewardingBlockUpdated", "type": "event" }, { "inputs": [], - "name": "WBNB", + "name": "INITIAL_INDEX", "outputs": [ { - "internalType": "address", + "internalType": "uint224", "name": "", - "type": "address" + "type": "uint224" } ], "stateMutability": "view", @@ -29775,10 +29601,10 @@ }, { "inputs": [], - "name": "comptrollerAddress", + "name": "accessControlManager", "outputs": [ { - "internalType": "address", + "internalType": "contract IAccessControlManagerV8", "name": "", "type": "address" } @@ -29787,119 +29613,170 @@ "type": "function" }, { - "inputs": [], - "name": "factory", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", "type": "address" } ], - "stateMutability": "view", + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" + "internalType": "address", + "name": "vToken", + "type": "address" }, { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" + "internalType": "address", + "name": "borrower", + "type": "address" }, { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountIn", - "outputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" } ], - "stateMutability": "pure", + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "internalType": "address", + "name": "vToken", + "type": "address" }, { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ { "internalType": "uint256", - "name": "reserveOut", + "name": "", "type": "uint256" } ], - "name": "getAmountOut", - "outputs": [ + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, { "internalType": "uint256", - "name": "amountOut", + "name": "amount", "type": "uint256" } ], - "stateMutability": "pure", + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, { "internalType": "uint256", - "name": "amountOut", + "name": "loopsLimit_", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "accessControlManager_", + "type": "address" } ], - "name": "getAmountsIn", - "outputs": [ + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "vToken", + "type": "address" } ], - "stateMutability": "view", + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "getAmountsOut", + "name": "lastContributorBlock", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], "stateMutability": "view", @@ -29907,12 +29784,12 @@ }, { "inputs": [], - "name": "owner", + "name": "maxLoopsLimit", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", @@ -29920,7 +29797,7 @@ }, { "inputs": [], - "name": "pendingOwner", + "name": "owner", "outputs": [ { "internalType": "address", @@ -29932,32 +29809,16 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveB", - "type": "uint256" - } - ], - "name": "quote", + "inputs": [], + "name": "pendingOwner", "outputs": [ { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { @@ -29968,347 +29829,251 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "rewardToken", + "outputs": [ { - "internalType": "address", - "name": "_vBNBAddress", + "internalType": "contract IERC20Upgradeable", + "name": "", "type": "address" } ], - "name": "setVBNBAddress", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapBNBForExactTokens", + "name": "rewardTokenAccrued", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ { "internalType": "uint256", - "name": "deadline", + "name": "", "type": "uint256" } ], - "name": "swapBNBForExactTokensAndRepay", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "", "type": "address" - }, + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" + "internalType": "uint224", + "name": "index", + "type": "uint224" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "uint32", + "name": "block", + "type": "uint32" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" } ], - "name": "swapBNBForExactTokensAndSupply", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "", "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ { "internalType": "uint256", - "name": "deadline", + "name": "", "type": "uint256" } ], - "name": "swapBNBForFullTokenDebtAndRepay", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactBNBForTokens", + "name": "rewardTokenContributorSpeeds", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "", "type": "address" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ { "internalType": "uint256", - "name": "deadline", + "name": "", "type": "uint256" } ], - "name": "swapExactBNBForTokensAndRepay", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ { "internalType": "uint256", - "name": "deadline", + "name": "", "type": "uint256" } ], - "name": "swapExactBNBForTokensAndRepayAtSupportingFee", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "", "type": "address" - }, + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "internalType": "uint224", + "name": "index", + "type": "uint224" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "uint32", + "name": "block", + "type": "uint32" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" } ], - "name": "swapExactBNBForTokensAndSupply", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "accessControlManager_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactBNBForTokensAndSupplyAtSupportingFee", + "name": "setAccessControlManager", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "contributor", "type": "address" }, { "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactBNBForTokensAtSupportingFee", - "outputs": [ - { - "internalType": "uint256", - "name": "swapAmount", + "name": "rewardTokenSpeed", "type": "uint256" } ], - "stateMutability": "payable", + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", + "internalType": "contract VToken[]", + "name": "vTokens", "type": "address[]" }, { - "internalType": "address", - "name": "to", - "type": "address" + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForBNB", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" } ], + "name": "setLastRewardingBlocks", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -30316,26 +30081,11 @@ "inputs": [ { "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", + "name": "limit", "type": "uint256" } ], - "name": "swapExactTokensForBNBAndRepay", + "name": "setMaxLoopsLimit", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -30343,27 +30093,35 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "swapExactTokensForBNBAndRepayAtSupportingFee", + "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -30371,27 +30129,12 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "contributor", + "type": "address" } ], - "name": "swapExactTokensForBNBAndSupply", + "name": "updateContributorRewards", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -30399,27 +30142,37 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "internalType": "address", + "name": "vToken", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "vToken", + "type": "address" } ], - "name": "swapExactTokensForBNBAndSupplyAtSupportingFee", + "name": "updateRewardTokenSupplyIndex", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -30427,76 +30180,107 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "internalType": "address", + "name": "_logic", + "type": "address" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "internalType": "address", + "name": "admin_", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RewardsDistributor_Tron_2_Proxy": { + "address": "0x507401883C2a874D919e78a73dD0cB56f2e7eaD7", + "abi": [ + { + "inputs": [ { "internalType": "address", - "name": "to", + "name": "_logic", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForBNBAtSupportingFee", - "outputs": [ + "internalType": "address", + "name": "admin_", + "type": "address" + }, { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "internalType": "bytes", + "name": "_data", + "type": "bytes" } ], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "to", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "name": "swapExactTokensForTokens", + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "admin_", + "type": "address" } ], "stateMutability": "nonpayable", @@ -30506,65 +30290,25 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAndRepay", + "name": "changeAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "implementation", + "outputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "implementation_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAndRepayAtSupportingFee", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -30572,31 +30316,11 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newImplementation", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAndSupply", + "name": "upgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -30605,69 +30329,86 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newImplementation", "type": "address" }, { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "swapExactTokensForTokensAndSupplyAtSupportingFee", + "name": "upgradeToAndCall", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "RewardsDistributor_Tron_3": { + "address": "0x1c50672f4752cc0Ae532D9b93b936C21121Ff08b", + "abi": [ + { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "to", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "name": "swapExactTokensForTokensAtSupportingFee", + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", "outputs": [ { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "internalType": "address", + "name": "admin_", + "type": "address" } ], "stateMutability": "nonpayable", @@ -30675,38 +30416,25 @@ }, { "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapTokensForExactBNB", + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "implementation_", + "type": "address" } ], "stateMutability": "nonpayable", @@ -30715,27 +30443,12 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "newImplementation", + "type": "address" } ], - "name": "swapTokensForExactBNBAndRepay", + "name": "upgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -30743,458 +30456,473 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "newImplementation", + "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "swapTokensForExactBNBAndSupply", + "name": "upgradeToAndCall", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, + { + "stateMutability": "payable", + "type": "receive" + }, { "inputs": [ { "internalType": "uint256", - "name": "amountOut", + "name": "loopsLimit", "type": "uint256" }, { "internalType": "uint256", - "name": "amountInMax", + "name": "requiredLoops", "type": "uint256" - }, + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "sender", + "type": "address" }, { "internalType": "address", - "name": "to", + "name": "calledContract", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "string", + "name": "methodSignature", + "type": "string" } ], - "name": "swapTokensForExactTokens", - "outputs": [ + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "contributor", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOut", + "name": "newSpeed", "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "rewardAccrued", "type": "uint256" } ], - "name": "swapTokensForExactTokensAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "ContributorRewardsUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "borrower", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOut", + "name": "rewardTokenDelta", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "rewardTokenTotal", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "rewardTokenBorrowIndex", "type": "uint256" } ], - "name": "swapTokensForExactTokensAndSupply", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "DistributedBorrowerRewardToken", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "rewardTokenDelta", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "rewardTokenSupplyIndex", "type": "uint256" } ], - "name": "swapTokensForFullBNBDebtAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "vToken", "type": "address" - }, + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "oldMaxLoopsLimit", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "newmaxLoopsLimit", "type": "uint256" } ], - "name": "swapTokensForFullTokenDebtAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "MaxLoopsLimitUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "contract IERC20", - "name": "token", + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", "type": "address" }, { + "indexed": false, "internalType": "address", - "name": "to", + "name": "newAccessControlManager", "type": "address" - }, - { - "internalType": "uint256", - "name": "sweepAmount", - "type": "uint256" } ], - "name": "sweepToken", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "NewAccessControlManager", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "previousOwner", "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "vBNBAddress", - "outputs": [ + }, { + "indexed": true, "internalType": "address", - "name": "", + "name": "newOwner", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "OwnershipTransferStarted", + "type": "event" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "SwapRouter_GameFi": { - "address": "0x5D254Bc7c7f2670395B9E0716C21249083D41a4f", - "abi": [ - { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "WBNB_", + "name": "previousOwner", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "factory_", + "name": "newOwner", "type": "address" - }, + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "_comptrollerAddress", + "name": "vToken", "type": "address" }, { - "internalType": "address", - "name": "_vBNBAddress", - "type": "address" + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" } ], - "stateMutability": "nonpayable", - "type": "constructor" + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amount", - "type": "uint256" + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountMax", + "name": "newSpeed", "type": "uint256" } ], - "name": "ExcessiveInputAmount", - "type": "error" - }, - { - "inputs": [], - "name": "IdenticalAddresses", - "type": "error" + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountIntMax", + "name": "amount", "type": "uint256" } ], - "name": "InputAmountAboveMaximum", - "type": "error" + "name": "RewardTokenGranted", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "sweepAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" } ], - "name": "InsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientInputAmount", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientLiquidity", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientOutputAmount", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidPath", - "type": "error" + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOutMin", + "name": "newSpeed", "type": "uint256" } ], - "name": "OutputAmountBelowMinimum", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrantCheck", - "type": "error" + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "address", - "name": "repayer", - "type": "address" - }, - { + "indexed": true, "internalType": "address", "name": "vToken", "type": "address" }, { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" } ], - "name": "RepayError", - "type": "error" - }, - { - "inputs": [], - "name": "SafeApproveFailed", - "type": "error" + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" }, { "inputs": [], - "name": "SafeTransferBNBFailed", - "type": "error" + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "SafeTransferFailed", - "type": "error" + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "SafeTransferFromFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "supplier", - "type": "address" - }, + "name": "accessControlManager", + "outputs": [ { - "internalType": "address", - "name": "vToken", + "internalType": "contract IAccessControlManagerV8", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" } ], - "name": "SupplyError", - "type": "error" + "stateMutability": "view", + "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "internalType": "address", + "name": "holder", + "type": "address" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" } ], - "name": "SwapAmountLessThanAmountOutMin", - "type": "error" + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "timestemp", - "type": "uint256" + "internalType": "address", + "name": "holder", + "type": "address" } ], - "name": "SwapDeadlineExpire", - "type": "error" + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [ @@ -31202,260 +30930,168 @@ "internalType": "address", "name": "vToken", "type": "address" - } - ], - "name": "VTokenNotListed", - "type": "error" - }, - { - "inputs": [ + }, { "internalType": "address", - "name": "underlying", + "name": "borrower", "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" } ], - "name": "VTokenUnderlyingInvalid", - "type": "error" + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "expectedAdddress", + "name": "vToken", "type": "address" }, { "internalType": "address", - "name": "passedAddress", + "name": "supplier", "type": "address" } ], - "name": "WrongAddress", - "type": "error" + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "ZeroAddress", - "type": "error" + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "recipient", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "OwnershipTransferStarted", - "type": "event" + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "previousOwner", + "internalType": "contract Comptroller", + "name": "comptroller_", "type": "address" }, { - "indexed": true, + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { "internalType": "address", - "name": "newOwner", + "name": "accessControlManager_", "type": "address" } ], - "name": "OwnershipTransferred", - "type": "event" + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "swapper", + "name": "vToken", "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "name": "SwapBnbForTokens", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "swapper", - "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - } - ], - "name": "SwapBnbForTokensAtSupportingFee", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "swapper", - "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "name": "SwapTokensForBnb", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "swapper", - "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" } ], - "name": "SwapTokensForBnbAtSupportingFee", - "type": "event" + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "swapper", + "name": "", "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" } ], - "name": "SwapTokensForTokens", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "swapper", - "type": "address" - }, + "name": "lastContributorBlock", + "outputs": [ { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "SwapTokensForTokensAtSupportingFee", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "sweepAmount", + "name": "", "type": "uint256" } ], - "name": "SweepToken", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "oldAddress", - "type": "address" - }, + "inputs": [], + "name": "owner", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "newAddress", + "name": "", "type": "address" } ], - "name": "VBNBAddressUpdated", - "type": "event" + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "WBNB", + "name": "pendingOwner", "outputs": [ { "internalType": "address", @@ -31468,17 +31104,17 @@ }, { "inputs": [], - "name": "acceptOwnership", + "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "comptrollerAddress", + "name": "rewardToken", "outputs": [ { - "internalType": "address", + "internalType": "contract IERC20Upgradeable", "name": "", "type": "address" } @@ -31487,95 +31123,67 @@ "type": "function" }, { - "inputs": [], - "name": "factory", - "outputs": [ + "inputs": [ { "internalType": "address", "name": "", "type": "address" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountIn", + "name": "rewardTokenAccrued", "outputs": [ { "internalType": "uint256", - "name": "amountIn", + "name": "", "type": "uint256" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "getAmountOut", + "name": "rewardTokenBorrowSpeeds", "outputs": [ { "internalType": "uint256", - "name": "amountOut", + "name": "", "type": "uint256" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "getAmountsIn", + "name": "rewardTokenBorrowState", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" } ], "stateMutability": "view", @@ -31584,48 +31192,41 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "getAmountsOut", + "name": "rewardTokenBorrowerIndex", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "inputs": [ { "internalType": "address", "name": "", "type": "address" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", + "name": "rewardTokenContributorSpeeds", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", @@ -31634,379 +31235,333 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveA", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" }, { - "internalType": "uint256", - "name": "reserveB", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "quote", + "name": "rewardTokenSupplierIndex", "outputs": [ { "internalType": "uint256", - "name": "amountB", + "name": "", "type": "uint256" } ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "_vBNBAddress", + "name": "", "type": "address" } ], - "name": "setVBNBAddress", - "outputs": [], - "stateMutability": "nonpayable", + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapBNBForExactTokens", + "name": "rewardTokenSupplyState", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" } ], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "accessControlManager_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapBNBForExactTokensAndRepay", + "name": "setAccessControlManager", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "contributor", "type": "address" }, { "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", + "name": "rewardTokenSpeed", "type": "uint256" } ], - "name": "swapBNBForExactTokensAndSupply", + "name": "setContributorRewardTokenSpeed", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "vTokenAddress", - "type": "address" + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" } ], - "name": "swapBNBForFullTokenDebtAndRepay", + "name": "setLastRewardingBlocks", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", - "name": "amountOutMin", + "name": "limit", "type": "uint256" - }, + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "address[]", - "name": "path", + "internalType": "contract VToken[]", + "name": "vTokens", "type": "address[]" }, { - "internalType": "address", - "name": "to", - "type": "address" + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactBNBForTokens", - "outputs": [ { "internalType": "uint256[]", - "name": "amounts", + "name": "borrowSpeeds", "type": "uint256[]" } ], - "stateMutability": "payable", + "name": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newOwner", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactBNBForTokensAndRepay", + "name": "transferOwnership", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "contributor", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactBNBForTokensAndRepayAtSupportingFee", + "name": "updateContributorRewards", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "vToken", "type": "address" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" } ], - "name": "swapExactBNBForTokensAndSupply", + "name": "updateRewardTokenBorrowIndex", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "vToken", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactBNBForTokensAndSupplyAtSupportingFee", + "name": "updateRewardTokenSupplyIndex", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "_logic", + "type": "address" }, { "internalType": "address", - "name": "to", + "name": "admin_", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "bytes", + "name": "_data", + "type": "bytes" } ], - "name": "swapExactBNBForTokensAtSupportingFee", - "outputs": [ + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RewardsDistributor_Tron_3_Proxy": { + "address": "0x1c50672f4752cc0Ae532D9b93b936C21121Ff08b", + "abi": [ + { + "inputs": [ { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" } ], "stateMutability": "payable", - "type": "function" + "type": "constructor" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "to", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "name": "swapExactTokensForBNB", + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "admin_", + "type": "address" } ], "stateMutability": "nonpayable", @@ -32015,83 +31570,38 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "name": "swapExactTokensForBNBAndRepay", + "name": "changeAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "inputs": [], + "name": "implementation", + "outputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "implementation_", + "type": "address" } ], - "name": "swapExactTokensForBNBAndRepayAtSupportingFee", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "newImplementation", + "type": "address" } ], - "name": "swapExactTokensForBNBAndSupply", + "name": "upgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -32099,104 +31609,87 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "newImplementation", + "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "swapExactTokensForBNBAndSupplyAtSupportingFee", + "name": "upgradeToAndCall", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "RiskFund": { + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "abi": [ + { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "address", - "name": "to", + "name": "previousAdmin", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "name": "swapExactTokensForBNBAtSupportingFee", - "outputs": [ + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": true, "internalType": "address", - "name": "to", + "name": "implementation", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokens", + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "admin_", + "type": "address" } ], "stateMutability": "nonpayable", @@ -32206,65 +31699,25 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAndRepay", + "name": "changeAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "implementation", + "outputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "implementation_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAndRepayAtSupportingFee", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -32272,31 +31725,11 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newImplementation", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAndSupply", + "name": "upgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -32305,367 +31738,362 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newImplementation", "type": "address" }, { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "swapExactTokensForTokensAndSupplyAtSupportingFee", + "name": "upgradeToAndCall", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ApproveFailed", + "type": "error" + }, { "inputs": [ { "internalType": "uint256", - "name": "amountIn", + "name": "loopsLimit", "type": "uint256" }, { "internalType": "uint256", - "name": "amountOutMin", + "name": "requiredLoops", "type": "uint256" - }, + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "sender", + "type": "address" }, { "internalType": "address", - "name": "to", + "name": "calledContract", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForTokensAtSupportingFee", - "outputs": [ - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "internalType": "string", + "name": "methodSignature", + "type": "string" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "to", + "name": "asset", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "amount", "type": "uint256" } ], - "name": "swapTokensForExactBNB", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" + "name": "AssetsReservesUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "oldConvertibleBaseAsset", + "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "newConvertibleBaseAsset", + "type": "address" } ], - "name": "swapTokensForExactBNBAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "ConvertibleBaseAssetUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "oldMaxLoopsLimit", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "newmaxLoopsLimit", "type": "uint256" } ], - "name": "swapTokensForExactBNBAndSupply", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "MaxLoopsLimitUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "amountOut", + "name": "oldMinAmountToConvert", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "newMinAmountToConvert", "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + } + ], + "name": "MinAmountToConvertUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address", - "name": "to", + "name": "oldAccessControlManager", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapTokensForExactTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "NewAccessControlManager", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "previousOwner", "type": "address" }, { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "swapTokensForExactTokensAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "OwnershipTransferStarted", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "previousOwner", "type": "address" }, { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "oldPancakeSwapRouter", + "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "newPancakeSwapRouter", + "type": "address" } ], - "name": "swapTokensForExactTokensAndSupply", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "PancakeSwapRouterUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" } ], - "name": "swapTokensForFullBNBDebtAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "PoolRegistryUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "oldShortfallContract", "type": "address" }, { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, + "indexed": true, + "internalType": "address", + "name": "newShortfallContract", + "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address[]", - "name": "path", + "name": "markets", "type": "address[]" }, { + "indexed": false, + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "totalAmount", "type": "uint256" } ], - "name": "swapTokensForFullTokenDebtAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "SwappedPoolsAssets", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "contract IERC20", + "indexed": true, + "internalType": "address", "name": "token", "type": "address" }, { + "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "sweepAmount", + "name": "amount", "type": "uint256" } ], - "name": "sweepToken", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "SweepToken", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "comptroller", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "transferOwnership", + "name": "TransferredReserveForAuction", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "vBNBAddress", + "name": "accessControlManager", "outputs": [ { - "internalType": "address", + "internalType": "contract IAccessControlManagerV8", "name": "", "type": "address" } @@ -32673,270 +32101,486 @@ "stateMutability": "view", "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "SwapRouter_LiquidStakedBNB": { - "address": "0xb16792E90d6478DaBbd0144e13f41CeA21ACE116", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "WBNB_", - "type": "address" - }, - { - "internalType": "address", - "name": "factory_", - "type": "address" - }, - { - "internalType": "address", - "name": "_comptrollerAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_vBNBAddress", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, + "name": "assetsReserves", + "outputs": [ { "internalType": "uint256", - "name": "amountMax", + "name": "", "type": "uint256" } ], - "name": "ExcessiveInputAmount", - "type": "error" + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "IdenticalAddresses", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, + "name": "convertibleBaseAsset", + "outputs": [ { - "internalType": "uint256", - "name": "amountIntMax", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "InputAmountAboveMaximum", - "type": "error" + "stateMutability": "view", + "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "sweepAmount", - "type": "uint256" + "internalType": "address", + "name": "comptroller", + "type": "address" }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ { "internalType": "uint256", - "name": "balance", + "name": "", "type": "uint256" } ], - "name": "InsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientInputAmount", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientLiquidity", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientOutputAmount", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidPath", - "type": "error" + "stateMutability": "view", + "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ { "internalType": "uint256", - "name": "amountOutMin", + "name": "", "type": "uint256" } ], - "name": "OutputAmountBelowMinimum", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrantCheck", - "type": "error" + "stateMutability": "view", + "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "repayer", - "type": "address" - }, - { - "internalType": "address", - "name": "vToken", + "name": "pancakeSwapRouter_", "type": "address" }, { "internalType": "uint256", - "name": "errorCode", + "name": "minAmountToConvert_", "type": "uint256" - } - ], - "name": "RepayError", - "type": "error" - }, - { - "inputs": [], - "name": "SafeApproveFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferBNBFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferFromFailed", - "type": "error" - }, - { - "inputs": [ + }, { "internalType": "address", - "name": "supplier", + "name": "convertibleBaseAsset_", "type": "address" }, { "internalType": "address", - "name": "vToken", + "name": "accessControlManager_", "type": "address" }, { "internalType": "uint256", - "name": "errorCode", + "name": "loopsLimit_", "type": "uint256" } ], - "name": "SupplyError", - "type": "error" + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ { "internalType": "uint256", - "name": "amountOutMin", + "name": "", "type": "uint256" } ], - "name": "SwapAmountLessThanAmountOutMin", - "type": "error" + "stateMutability": "view", + "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, + "inputs": [], + "name": "minAmountToConvert", + "outputs": [ { "internalType": "uint256", - "name": "timestemp", + "name": "", "type": "uint256" } ], - "name": "SwapDeadlineExpire", - "type": "error" + "stateMutability": "view", + "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "owner", + "outputs": [ { "internalType": "address", - "name": "vToken", + "name": "", "type": "address" } ], - "name": "VTokenNotListed", - "type": "error" + "stateMutability": "view", + "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "pancakeSwapRouter", + "outputs": [ { "internalType": "address", - "name": "underlying", + "name": "", "type": "address" } ], - "name": "VTokenUnderlyingInvalid", - "type": "error" + "stateMutability": "view", + "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "expectedAdddress", + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convertibleBaseAsset", + "type": "address" + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + } + ], + "name": "setMinAmountToConvert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + } + ], + "name": "setPancakeSwapRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "shortfallContractAddress_", + "type": "address" + } + ], + "name": "setShortfallContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "internalType": "address[][]", + "name": "paths", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapPoolsAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", "type": "address" }, { "internalType": "address", - "name": "passedAddress", + "name": "_to", "type": "address" } ], - "name": "WrongAddress", + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferReserveForAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "RiskFund_Implementation": { + "address": "0x665085EcC7bc1B59c9872d030f2Bd6c724739709", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ApproveFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", "type": "error" }, { "inputs": [], - "name": "ZeroAddress", + "name": "ZeroAddressNotAllowed", "type": "error" }, { @@ -32945,17 +32589,23 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "comptroller", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "asset", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "OwnershipTransferStarted", + "name": "AssetsReservesUpdated", "type": "event" }, { @@ -32964,61 +32614,87 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "oldConvertibleBaseAsset", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "newConvertibleBaseAsset", "type": "address" } ], - "name": "OwnershipTransferred", + "name": "ConvertibleBaseAssetUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "swapper", - "type": "address" + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" }, { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinAmountToConvert", + "type": "uint256" }, { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "indexed": false, + "internalType": "uint256", + "name": "newMinAmountToConvert", + "type": "uint256" } ], - "name": "SwapBnbForTokens", + "name": "MinAmountToConvertUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "swapper", + "name": "oldAccessControlManager", "type": "address" }, { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" } ], - "name": "SwapBnbForTokensAtSupportingFee", + "name": "NewAccessControlManager", "type": "event" }, { @@ -33027,23 +32703,17 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "previousOwner", "type": "address" }, { "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "SwapTokensForBnb", + "name": "OwnershipTransferStarted", "type": "event" }, { @@ -33052,17 +32722,17 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "previousOwner", "type": "address" }, { "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "SwapTokensForBnbAtSupportingFee", + "name": "OwnershipTransferred", "type": "event" }, { @@ -33071,23 +32741,17 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "oldPancakeSwapRouter", "type": "address" }, { "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "newPancakeSwapRouter", + "type": "address" } ], - "name": "SwapTokensForTokens", + "name": "PancakeSwapRouterUpdated", "type": "event" }, { @@ -33096,17 +32760,17 @@ { "indexed": true, "internalType": "address", - "name": "swapper", + "name": "oldPoolRegistry", "type": "address" }, { "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" } ], - "name": "SwapTokensForTokensAtSupportingFee", + "name": "PoolRegistryUpdated", "type": "event" }, { @@ -33115,23 +32779,42 @@ { "indexed": true, "internalType": "address", - "name": "token", + "name": "oldShortfallContract", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "to", + "name": "newShortfallContract", "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" }, { "indexed": false, "internalType": "uint256", - "name": "sweepAmount", + "name": "totalAmount", "type": "uint256" } ], - "name": "SweepToken", + "name": "SwappedPoolsAssets", "type": "event" }, { @@ -33140,31 +32823,43 @@ { "indexed": true, "internalType": "address", - "name": "oldAddress", + "name": "token", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newAddress", + "name": "to", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "VBNBAddressUpdated", + "name": "SweepToken", "type": "event" }, { - "inputs": [], - "name": "WBNB", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "comptroller", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "TransferredReserveForAuction", + "type": "event" }, { "inputs": [], @@ -33175,20 +32870,39 @@ }, { "inputs": [], - "name": "comptrollerAddress", + "name": "accessControlManager", "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", "name": "", "type": "address" } ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "factory", + "name": "convertibleBaseAsset", "outputs": [ { "internalType": "address", @@ -33202,104 +32916,113 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" + "internalType": "address", + "name": "comptroller", + "type": "address" }, { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" + "internalType": "address", + "name": "asset", + "type": "address" } ], - "name": "getAmountIn", + "name": "getPoolAssetReserve", "outputs": [ { "internalType": "uint256", - "name": "amountIn", + "name": "", "type": "uint256" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ { "internalType": "uint256", - "name": "amountIn", + "name": "", "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" }, { "internalType": "uint256", - "name": "reserveIn", + "name": "minAmountToConvert_", "type": "uint256" }, { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountOut", - "outputs": [ + "internalType": "address", + "name": "convertibleBaseAsset_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, { "internalType": "uint256", - "name": "amountOut", + "name": "loopsLimit_", "type": "uint256" } ], - "stateMutability": "pure", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ { "internalType": "uint256", - "name": "amountOut", + "name": "", "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - } - ], - "name": "getAmountsIn", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "minAmountToConvert", + "outputs": [ { "internalType": "uint256", - "name": "amountIn", + "name": "", "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" } ], - "name": "getAmountsOut", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "", + "type": "address" } ], "stateMutability": "view", @@ -33307,7 +33030,7 @@ }, { "inputs": [], - "name": "owner", + "name": "pancakeSwapRouter", "outputs": [ { "internalType": "address", @@ -33332,32 +33055,16 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveB", - "type": "uint256" - } - ], - "name": "quote", + "inputs": [], + "name": "poolRegistry", "outputs": [ { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { @@ -33371,144 +33078,122 @@ "inputs": [ { "internalType": "address", - "name": "_vBNBAddress", + "name": "accessControlManager_", "type": "address" } ], - "name": "setVBNBAddress", + "name": "setAccessControlManager", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "_convertibleBaseAsset", "type": "address" - }, + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", - "name": "deadline", + "name": "limit", "type": "uint256" } ], - "name": "swapBNBForExactTokens", - "outputs": [ + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" } ], - "stateMutability": "payable", + "name": "setMinAmountToConvert", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "pancakeSwapRouter_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapBNBForExactTokensAndRepay", + "name": "setPancakeSwapRouter", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "poolRegistry_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapBNBForExactTokensAndSupply", + "name": "setPoolRegistry", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "shortfallContractAddress_", "type": "address" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapBNBForFullTokenDebtAndRepay", + "name": "setShortfallContractAddress", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "shortfall", + "outputs": [ { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "address[]", - "name": "path", + "name": "markets", "type": "address[]" }, { - "internalType": "address", - "name": "to", - "type": "address" + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "internalType": "address[][]", + "name": "paths", + "type": "address[][]" }, { "internalType": "uint256", @@ -33516,310 +33201,213 @@ "type": "uint256" } ], - "name": "swapExactBNBForTokens", + "name": "swapPoolsAssets", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "_token", "type": "address" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "_to", + "type": "address" } ], - "name": "swapExactBNBForTokensAndRepay", + "name": "sweepToken", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newOwner", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactBNBForTokensAndRepayAtSupportingFee", + "name": "transferOwnership", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "comptroller", "type": "address" }, { "internalType": "uint256", - "name": "amountOutMin", + "name": "amount", "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + } + ], + "name": "transferReserveForAuction", + "outputs": [ { "internalType": "uint256", - "name": "deadline", + "name": "", "type": "uint256" } ], - "name": "swapExactBNBForTokensAndSupply", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "comptroller", "type": "address" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "asset", + "type": "address" } ], - "name": "swapExactBNBForTokensAndSupplyAtSupportingFee", + "name": "updateAssetsState", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" - }, + } + ] + }, + "RiskFund_Proxy": { + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "abi": [ { "inputs": [ { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "_logic", + "type": "address" }, { "internalType": "address", - "name": "to", + "name": "admin_", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactBNBForTokensAtSupportingFee", - "outputs": [ - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "internalType": "bytes", + "name": "_data", + "type": "bytes" } ], "stateMutability": "payable", - "type": "function" + "type": "constructor" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "address", - "name": "to", + "name": "previousAdmin", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "name": "swapExactTokensForBNB", - "outputs": [ + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "admin_", + "type": "address" } ], - "name": "swapExactTokensForBNBAndRepay", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "name": "swapExactTokensForBNBAndRepayAtSupportingFee", + "name": "changeAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "inputs": [], + "name": "implementation", + "outputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "implementation_", + "type": "address" } ], - "name": "swapExactTokensForBNBAndSupply", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "newImplementation", + "type": "address" } ], - "name": "swapExactTokensForBNBAndSupplyAtSupportingFee", + "name": "upgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -33827,37 +33415,87 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "internalType": "address", + "name": "newImplementation", + "type": "address" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "Shortfall": { + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "abi": [ + { + "anonymous": false, + "inputs": [ { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" }, { + "indexed": false, "internalType": "address", - "name": "to", + "name": "newAdmin", "type": "address" - }, + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" } ], - "name": "swapExactTokensForBNBAtSupportingFee", + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", "outputs": [ { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "internalType": "address", + "name": "admin_", + "type": "address" } ], "stateMutability": "nonpayable", @@ -33865,38 +33503,25 @@ }, { "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokens", + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "implementation_", + "type": "address" } ], "stateMutability": "nonpayable", @@ -33906,31 +33531,11 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newImplementation", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAndRepay", + "name": "upgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -33939,1764 +33544,1539 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newImplementation", "type": "address" }, { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "swapExactTokensForTokensAndRepayAtSupportingFee", + "name": "upgradeToAndCall", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, + { + "stateMutability": "payable", + "type": "receive" + }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "token", "type": "address" }, { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "internalType": "address", + "name": "recipient", + "type": "address" }, { "internalType": "uint256", - "name": "amountOutMin", + "name": "amount", "type": "uint256" }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "uint256", - "name": "deadline", + "name": "availableBalance", "type": "uint256" } ], - "name": "swapExactTokensForTokensAndSupply", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "InsufficientBalance", + "type": "error" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "token", "type": "address" }, { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "internalType": "address", + "name": "user", + "type": "address" }, { "internalType": "uint256", - "name": "amountOutMin", + "name": "owedAmount", "type": "uint256" }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "uint256", - "name": "deadline", + "name": "amount", "type": "uint256" } ], - "name": "swapExactTokensForTokensAndSupplyAtSupportingFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "InsufficientDebt", + "type": "error" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "sender", + "type": "address" }, { "internalType": "address", - "name": "to", + "name": "calledContract", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForTokensAtSupportingFee", - "outputs": [ - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "internalType": "string", + "name": "methodSignature", + "type": "string" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "auctionStartBlock", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": true, "internalType": "address", - "name": "to", + "name": "highestBidder", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapTokensForExactBNB", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", + "name": "highestBidBps", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "seizedRiskFind", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", "type": "address[]" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": false, + "internalType": "uint256[]", + "name": "marketDebt", + "type": "uint256[]" } ], - "name": "swapTokensForExactBNBAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "AuctionClosed", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "auctionStartBlock", "type": "uint256" } ], - "name": "swapTokensForExactBNBAndSupply", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "AuctionRestarted", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "auctionStartBlock", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", + "indexed": false, + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", "type": "address[]" }, { - "internalType": "address", - "name": "to", - "type": "address" + "indexed": false, + "internalType": "uint256[]", + "name": "marketsDebt", + "type": "uint256[]" }, { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBidBps", "type": "uint256" } ], - "name": "swapTokensForExactTokens", - "outputs": [ + "name": "AuctionStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "AuctionsPaused", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "vTokenAddress", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOut", + "name": "auctionStartBlock", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "bidBps", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "bidder", + "type": "address" } ], - "name": "swapTokensForExactTokensAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "BidPlaced", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "address", - "name": "vTokenAddress", - "type": "address" - }, - { + "indexed": false, "internalType": "uint256", - "name": "amountOut", + "name": "oldIncentiveBps", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "newIncentiveBps", "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + } + ], + "name": "IncentiveBpsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" } ], - "name": "swapTokensForExactTokensAndSupply", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "Initialized", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "oldMinimumPoolBadDebt", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "newMinimumPoolBadDebt", "type": "uint256" } ], - "name": "swapTokensForFullBNBDebtAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "MinimumPoolBadDebtUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "vTokenAddress", + "name": "oldAccessControlManager", "type": "address" }, { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, "internalType": "uint256", - "name": "amountInMax", + "name": "oldNextBidderBlockLimit", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "newNextBidderBlockLimit", "type": "uint256" } ], - "name": "swapTokensForFullTokenDebtAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "NextBidderBlockLimitUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "contract IERC20", - "name": "token", + "indexed": true, + "internalType": "address", + "name": "previousOwner", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "to", + "name": "newOwner", "type": "address" - }, - { - "internalType": "uint256", - "name": "sweepAmount", - "type": "uint256" } ], - "name": "sweepToken", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "OwnershipTransferStarted", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "previousOwner", "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "vBNBAddress", - "outputs": [ + }, { + "indexed": true, "internalType": "address", - "name": "", + "name": "newOwner", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "OwnershipTransferred", + "type": "event" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "SwapRouter_StableCoins": { - "address": "0x8Ff3c0a74b4CBD4dFA3A35Cca756490bE351F936", - "abi": [ - { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "WBNB_", + "name": "oldPoolRegistry", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "factory_", + "name": "newPoolRegistry", "type": "address" - }, + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "_comptrollerAddress", + "name": "token", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "_vBNBAddress", + "name": "user", "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "amountMax", + "name": "amount", "type": "uint256" } ], - "name": "ExcessiveInputAmount", - "type": "error" - }, - { - "inputs": [], - "name": "IdenticalAddresses", - "type": "error" + "name": "TokenDebtAdded", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountIntMax", + "name": "amount", "type": "uint256" } ], - "name": "InputAmountAboveMaximum", - "type": "error" + "name": "TokenDebtClaimed", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "sweepAmount", + "name": "oldWaitForFirstBidder", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "balance", + "name": "newWaitForFirstBidder", "type": "uint256" } ], - "name": "InsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientInputAmount", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientLiquidity", - "type": "error" + "name": "WaitForFirstBidderUpdated", + "type": "event" }, { "inputs": [], - "name": "InsufficientOutputAmount", - "type": "error" + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "InvalidPath", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, + "name": "accessControlManager", + "outputs": [ { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" } ], - "name": "OutputAmountBelowMinimum", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrantCheck", - "type": "error" + "stateMutability": "view", + "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "repayer", + "name": "", "type": "address" + } + ], + "name": "auctions", + "outputs": [ + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" }, { - "internalType": "address", - "name": "vToken", - "type": "address" + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "internalType": "enum Shortfall.AuctionStatus", + "name": "status", + "type": "uint8" }, { "internalType": "uint256", - "name": "errorCode", + "name": "seizedRiskFund", "type": "uint256" - } - ], - "name": "RepayError", - "type": "error" - }, - { - "inputs": [], - "name": "SafeApproveFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferBNBFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferFailed", - "type": "error" - }, - { - "inputs": [], - "name": "SafeTransferFromFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "supplier", - "type": "address" }, { "internalType": "address", - "name": "vToken", + "name": "highestBidder", "type": "address" }, { "internalType": "uint256", - "name": "errorCode", + "name": "highestBidBps", "type": "uint256" - } - ], - "name": "SupplyError", - "type": "error" - }, - { - "inputs": [ + }, { "internalType": "uint256", - "name": "swapAmount", + "name": "highestBidBlock", "type": "uint256" }, { "internalType": "uint256", - "name": "amountOutMin", + "name": "startBidBps", "type": "uint256" } ], - "name": "SwapAmountLessThanAmountOutMin", - "type": "error" + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "contract IERC20Upgradeable", + "name": "token", + "type": "address" }, { "internalType": "uint256", - "name": "timestemp", + "name": "amount_", "type": "uint256" } ], - "name": "SwapDeadlineExpire", - "type": "error" + "name": "claimTokenDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "comptroller", "type": "address" } ], - "name": "VTokenNotListed", - "type": "error" + "name": "closeAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "incentiveBps", + "outputs": [ { - "internalType": "address", - "name": "underlying", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "VTokenUnderlyingInvalid", - "type": "error" + "stateMutability": "view", + "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "expectedAdddress", + "internalType": "contract IRiskFund", + "name": "riskFund_", "type": "address" }, + { + "internalType": "uint256", + "name": "minimumPoolBadDebt_", + "type": "uint256" + }, { "internalType": "address", - "name": "passedAddress", + "name": "accessControlManager_", "type": "address" } ], - "name": "WrongAddress", - "type": "error" + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "ZeroAddress", - "type": "error" + "name": "minimumPoolBadDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, + "inputs": [], + "name": "nextBidderBlockLimit", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "OwnershipTransferStarted", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "owner", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "", "type": "address" - }, + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "", "type": "address" } ], - "name": "OwnershipTransferred", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "swapper", + "name": "comptroller", "type": "address" }, { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" }, { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" } ], - "name": "SwapBnbForTokens", - "type": "event" + "name": "placeBid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "poolRegistry", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "swapper", + "name": "", "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" } ], - "name": "SwapBnbForTokensAtSupportingFee", - "type": "event" + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "swapper", + "name": "comptroller", "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" } ], - "name": "SwapTokensForBnb", - "type": "event" + "name": "restartAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "resumeAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "swapper", + "internalType": "contract IRiskFund", + "name": "", "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" } ], - "name": "SwapTokensForBnbAtSupportingFee", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "swapper", + "name": "accessControlManager_", "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "indexed": true, - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" } ], - "name": "SwapTokensForTokens", - "type": "event" + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "swapper", + "name": "comptroller", "type": "address" - }, - { - "indexed": true, - "internalType": "address[]", - "name": "path", - "type": "address[]" } ], - "name": "SwapTokensForTokensAtSupportingFee", - "type": "event" + "name": "startAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "token", + "internalType": "contract IERC20Upgradeable", + "name": "", "type": "address" }, { - "indexed": true, "internalType": "address", - "name": "to", + "name": "", "type": "address" - }, + } + ], + "name": "tokenDebt", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "sweepAmount", + "name": "", "type": "uint256" } ], - "name": "SweepToken", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "oldAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newAddress", + "internalType": "contract IERC20Upgradeable", + "name": "", "type": "address" } ], - "name": "VBNBAddressUpdated", - "type": "event" - }, - { - "inputs": [], - "name": "WBNB", + "name": "totalTokenDebt", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "comptrollerAddress", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "newOwner", "type": "address" } ], - "stateMutability": "view", + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "factory", - "outputs": [ + "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "_incentiveBps", + "type": "uint256" } ], - "stateMutability": "view", + "name": "updateIncentiveBps", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountIn", - "outputs": [ - { - "internalType": "uint256", - "name": "amountIn", + "name": "_minimumPoolBadDebt", "type": "uint256" } ], - "stateMutability": "pure", + "name": "updateMinimumPoolBadDebt", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountOut", - "outputs": [ - { - "internalType": "uint256", - "name": "amountOut", + "name": "_nextBidderBlockLimit", "type": "uint256" } ], - "stateMutability": "pure", + "name": "updateNextBidderBlockLimit", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - } - ], - "name": "getAmountsIn", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "poolRegistry_", + "type": "address" } ], - "stateMutability": "view", + "name": "updatePoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", - "name": "amountIn", + "name": "_waitForFirstBidder", "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - } - ], - "name": "getAmountsOut", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" } ], - "stateMutability": "view", + "name": "updateWaitForFirstBidder", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "owner", + "name": "waitForFirstBidder", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "_logic", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" }, { - "internalType": "uint256", - "name": "reserveA", - "type": "uint256" + "internalType": "address", + "name": "admin_", + "type": "address" }, { - "internalType": "uint256", - "name": "reserveB", - "type": "uint256" - } - ], - "name": "quote", - "outputs": [ - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" + "internalType": "bytes", + "name": "_data", + "type": "bytes" } ], - "stateMutability": "pure", - "type": "function" - }, + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "Shortfall_Implementation": { + "address": "0x40Ec22d1aA01236dE2FB3dF049DE9f104A25c87C", + "abi": [ { "inputs": [], - "name": "renounceOwnership", - "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "constructor" }, { "inputs": [ { "internalType": "address", - "name": "_vBNBAddress", + "name": "token", "type": "address" - } - ], - "name": "setVBNBAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" }, { "internalType": "address", - "name": "to", + "name": "recipient", "type": "address" }, { "internalType": "uint256", - "name": "deadline", + "name": "amount", "type": "uint256" - } - ], - "name": "swapBNBForExactTokens", - "outputs": [ + }, { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "uint256", + "name": "availableBalance", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "function" + "name": "InsufficientBalance", + "type": "error" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "token", "type": "address" }, { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" + "internalType": "address", + "name": "user", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "uint256", + "name": "owedAmount", + "type": "uint256" }, { "internalType": "uint256", - "name": "deadline", + "name": "amount", "type": "uint256" } ], - "name": "swapBNBForExactTokensAndRepay", - "outputs": [], - "stateMutability": "payable", - "type": "function" + "name": "InsufficientDebt", + "type": "error" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "sender", "type": "address" }, { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "address", + "name": "calledContract", + "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "string", + "name": "methodSignature", + "type": "string" } ], - "name": "swapBNBForExactTokensAndSupply", - "outputs": [], - "stateMutability": "payable", - "type": "function" + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "comptroller", "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" }, { + "indexed": true, + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "highestBidBps", "type": "uint256" - } - ], - "name": "swapBNBForFullTokenDebtAndRepay", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ + }, { + "indexed": false, "internalType": "uint256", - "name": "amountOutMin", + "name": "seizedRiskFind", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", "type": "address[]" }, { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactBNBForTokens", - "outputs": [ - { + "indexed": false, "internalType": "uint256[]", - "name": "amounts", + "name": "marketDebt", "type": "uint256[]" } ], - "stateMutability": "payable", - "type": "function" + "name": "AuctionClosed", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "comptroller", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", + "name": "auctionStartBlock", "type": "uint256" } ], - "name": "swapExactBNBForTokensAndRepay", - "outputs": [], - "stateMutability": "payable", - "type": "function" + "name": "AuctionRestarted", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "comptroller", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOutMin", + "name": "auctionStartBlock", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", + "indexed": false, + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", "type": "address[]" }, { + "indexed": false, + "internalType": "uint256[]", + "name": "marketsDebt", + "type": "uint256[]" + }, + { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBidBps", "type": "uint256" } ], - "name": "swapExactBNBForTokensAndRepayAtSupportingFee", - "outputs": [], - "stateMutability": "payable", - "type": "function" + "name": "AuctionStarted", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "vTokenAddress", + "name": "sender", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + } + ], + "name": "AuctionsPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" } ], - "name": "swapExactBNBForTokensAndSupply", - "outputs": [], - "stateMutability": "payable", - "type": "function" + "name": "AuctionsResumed", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vTokenAddress", + "name": "comptroller", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOutMin", + "name": "auctionStartBlock", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "bidBps", "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "bidder", + "type": "address" } ], - "name": "swapExactBNBForTokensAndSupplyAtSupportingFee", - "outputs": [], - "stateMutability": "payable", - "type": "function" + "name": "BidPlaced", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "amountOutMin", + "name": "oldIncentiveBps", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "newIncentiveBps", "type": "uint256" } ], - "name": "swapExactBNBForTokensAtSupportingFee", - "outputs": [ + "name": "IncentiveBpsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" } ], - "stateMutability": "payable", - "type": "function" + "name": "Initialized", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "amountIn", + "name": "oldMinimumPoolBadDebt", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "amountOutMin", + "name": "newMinimumPoolBadDebt", "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + } + ], + "name": "MinimumPoolBadDebtUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address", - "name": "to", + "name": "oldAccessControlManager", "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForBNB", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "NewAccessControlManager", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", + "name": "oldNextBidderBlockLimit", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "newNextBidderBlockLimit", "type": "uint256" } ], - "name": "swapExactTokensForBNBAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "NextBidderBlockLimitUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "swapExactTokensForBNBAndRepayAtSupportingFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "OwnershipTransferStarted", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" }, { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" } ], - "name": "swapExactTokensForBNBAndSupply", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "PoolRegistryUpdated", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "amount", "type": "uint256" } ], - "name": "swapExactTokensForBNBAndSupplyAtSupportingFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "TokenDebtAdded", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "to", + "name": "user", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForBNBAtSupportingFee", - "outputs": [ - { - "internalType": "uint256", - "name": "swapAmount", + "name": "amount", "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "TokenDebtClaimed", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", + "name": "oldWaitForFirstBidder", "type": "uint256" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { + "indexed": false, "internalType": "uint256", - "name": "deadline", + "name": "newWaitForFirstBidder", "type": "uint256" } ], - "name": "swapExactTokensForTokens", + "name": "WaitForFirstBidderUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "", "type": "address" - }, + } + ], + "name": "auctions", + "outputs": [ { "internalType": "uint256", - "name": "amountIn", + "name": "startBlock", "type": "uint256" }, { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" + "internalType": "enum Shortfall.AuctionStatus", + "name": "status", + "type": "uint8" }, { "internalType": "uint256", - "name": "deadline", + "name": "seizedRiskFund", "type": "uint256" - } - ], - "name": "swapExactTokensForTokensAndRepay", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, { "internalType": "address", - "name": "vTokenAddress", + "name": "highestBidder", "type": "address" }, { "internalType": "uint256", - "name": "amountIn", + "name": "highestBidBps", "type": "uint256" }, { "internalType": "uint256", - "name": "amountOutMin", + "name": "highestBidBlock", "type": "uint256" }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "uint256", - "name": "deadline", + "name": "startBidBps", "type": "uint256" } ], - "name": "swapExactTokensForTokensAndRepayAtSupportingFee", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "vTokenAddress", + "internalType": "contract IERC20Upgradeable", + "name": "token", "type": "address" }, { "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", + "name": "amount_", "type": "uint256" } ], - "name": "swapExactTokensForTokensAndSupply", + "name": "claimTokenDebt", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -35705,237 +35085,195 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "comptroller", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAndSupplyAtSupportingFee", + "name": "closeAuction", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "incentiveBps", + "outputs": [ { "internalType": "uint256", - "name": "amountIn", + "name": "", "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IRiskFund", + "name": "riskFund_", + "type": "address" }, { "internalType": "uint256", - "name": "amountOutMin", + "name": "minimumPoolBadDebt_", "type": "uint256" }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "accessControlManager_", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapExactTokensForTokensAtSupportingFee", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minimumPoolBadDebt", "outputs": [ { "internalType": "uint256", - "name": "swapAmount", + "name": "", "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, + "inputs": [], + "name": "nextBidderBlockLimit", + "outputs": [ { "internalType": "uint256", - "name": "amountInMax", + "name": "", "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ { "internalType": "address", - "name": "to", + "name": "", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapTokensForExactBNB", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "", + "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" + "internalType": "address", + "name": "comptroller", + "type": "address" }, { "internalType": "uint256", - "name": "amountInMax", + "name": "bidBps", "type": "uint256" }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "uint256", - "name": "deadline", + "name": "auctionStartBlock", "type": "uint256" } ], - "name": "swapTokensForExactBNBAndRepay", + "name": "placeBid", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "inputs": [], + "name": "poolRegistry", + "outputs": [ { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "swapTokensForExactBNBAndSupply", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, { "internalType": "address", - "name": "to", + "name": "comptroller", "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapTokensForExactTokens", + "name": "restartAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resumeAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", "outputs": [ { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "contract IRiskFund", + "name": "", + "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "accessControlManager_", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapTokensForExactTokensAndRepay", + "name": "setAccessControlManager", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -35944,31 +35282,11 @@ "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "comptroller", "type": "address" - }, - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" } ], - "name": "swapTokensForExactTokensAndSupply", + "name": "startAuction", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -35976,50 +35294,94 @@ { "inputs": [ { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" }, { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDebt", + "outputs": [ { "internalType": "uint256", - "name": "deadline", + "name": "", "type": "uint256" } ], - "name": "swapTokensForFullBNBDebtAndRepay", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalTokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vTokenAddress", + "name": "newOwner", "type": "address" - }, + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", - "name": "amountInMax", + "name": "_incentiveBps", "type": "uint256" - }, + } + ], + "name": "updateIncentiveBps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, + "internalType": "uint256", + "name": "_minimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "updateMinimumPoolBadDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", - "name": "deadline", + "name": "_nextBidderBlockLimit", "type": "uint256" } ], - "name": "swapTokensForFullTokenDebtAndRepay", + "name": "updateNextBidderBlockLimit", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -36027,23 +35389,127 @@ { "inputs": [ { - "internalType": "contract IERC20", - "name": "token", + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "updatePoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_waitForFirstBidder", + "type": "uint256" + } + ], + "name": "updateWaitForFirstBidder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "waitForFirstBidder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "Shortfall_Proxy": { + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", "type": "address" }, { "internalType": "address", - "name": "to", + "name": "admin_", "type": "address" }, { - "internalType": "uint256", - "name": "sweepAmount", - "type": "uint256" + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" } ], - "name": "sweepToken", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -36051,26 +35517,57 @@ "inputs": [ { "internalType": "address", - "name": "newOwner", + "name": "newAdmin", "type": "address" } ], - "name": "transferOwnership", + "name": "changeAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "vBNBAddress", + "name": "implementation", "outputs": [ { "internalType": "address", - "name": "", + "name": "implementation_", "type": "address" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { @@ -36079,8 +35576,8 @@ } ] }, - "SwapRouter_Tron": { - "address": "0x1D8cA5AFB88F07489786A3d2E0FF50F3F9314d97", + "SwapRouter_DeFi": { + "address": "0x89Bc8dFe0Af08b60ec285071d133FCdfa9B3C08e", "abi": [ { "inputs": [ @@ -37779,384 +37276,265 @@ } ] }, - "VTokenBeacon": { - "address": "0xBF85A90673E61956f8c79b9150BAB7893b791bDd", + "SwapRouter_GameFi": { + "address": "0x5D254Bc7c7f2670395B9E0716C21249083D41a4f", "abi": [ { "inputs": [ { "internalType": "address", - "name": "implementation_", + "name": "WBNB_", "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "factory_", "type": "address" }, { - "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "_comptrollerAddress", "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "_vBNBAddress", "type": "address" } ], - "name": "Upgraded", - "type": "event" + "stateMutability": "nonpayable", + "type": "constructor" }, { - "inputs": [], - "name": "implementation", - "outputs": [ + "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "amountMax", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "ExcessiveInputAmount", + "type": "error" }, { "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "IdenticalAddresses", + "type": "error" }, { "inputs": [ { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, { - "internalType": "address", - "name": "newImplementation", - "type": "address" + "internalType": "uint256", + "name": "amountIntMax", + "type": "uint256" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ] - }, - "VTokenImpl": { - "address": "0x91D2c7BCA6Ea3313E07e0F6B3D0D00c4Fae482df", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" + "name": "InputAmountAboveMaximum", + "type": "error" }, { "inputs": [ { "internalType": "uint256", - "name": "actualAddAmount", + "name": "sweepAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balance", "type": "uint256" } ], - "name": "AddReservesFactorFreshCheck", + "name": "InsufficientBalance", "type": "error" }, { "inputs": [], - "name": "BorrowCashNotAvailable", + "name": "InsufficientInputAmount", "type": "error" }, { "inputs": [], - "name": "BorrowFreshnessCheck", + "name": "InsufficientLiquidity", "type": "error" }, { "inputs": [], - "name": "ForceLiquidateBorrowUnauthorized", + "name": "InsufficientOutputAmount", "type": "error" }, { "inputs": [], - "name": "HealBorrowUnauthorized", + "name": "InvalidPath", "type": "error" }, { "inputs": [ { "internalType": "uint256", - "name": "errorCode", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", "type": "uint256" } ], - "name": "LiquidateAccrueCollateralInterestFailed", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateCloseAmountIsUintMax", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateCloseAmountIsZero", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateCollateralFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateLiquidatorIsBorrower", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateSeizeLiquidatorIsBorrower", - "type": "error" - }, - { - "inputs": [], - "name": "MintFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "ProtocolSeizeShareTooBig", - "type": "error" - }, - { - "inputs": [], - "name": "RedeemFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "RedeemTransferOutNotPossible", - "type": "error" - }, - { - "inputs": [], - "name": "ReduceReservesCashNotAvailable", - "type": "error" - }, - { - "inputs": [], - "name": "ReduceReservesCashValidation", + "name": "OutputAmountBelowMinimum", "type": "error" }, { "inputs": [], - "name": "ReduceReservesFreshCheck", + "name": "ReentrantCheck", "type": "error" }, { - "inputs": [], - "name": "RepayBorrowFreshnessCheck", + "inputs": [ + { + "internalType": "address", + "name": "repayer", + "type": "address" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "RepayError", "type": "error" }, { "inputs": [], - "name": "SetInterestRateModelFreshCheck", + "name": "SafeApproveFailed", "type": "error" }, { "inputs": [], - "name": "SetReserveFactorBoundsCheck", + "name": "SafeTransferBNBFailed", "type": "error" }, { "inputs": [], - "name": "SetReserveFactorFreshCheck", + "name": "SafeTransferFailed", "type": "error" }, { "inputs": [], - "name": "TransferNotAllowed", + "name": "SafeTransferFromFailed", "type": "error" }, { "inputs": [ { "internalType": "address", - "name": "sender", + "name": "supplier", "type": "address" }, { "internalType": "address", - "name": "calledContract", + "name": "vToken", "type": "address" }, { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" } ], - "name": "Unauthorized", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddressNotAllowed", + "name": "SupplyError", "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "uint256", - "name": "cashPrior", + "name": "swapAmount", "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "interestAccumulated", + "name": "amountOutMin", "type": "uint256" - }, + } + ], + "name": "SwapAmountLessThanAmountOutMin", + "type": "error" + }, + { + "inputs": [ { - "indexed": false, "internalType": "uint256", - "name": "borrowIndex", + "name": "deadline", "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "totalBorrows", + "name": "timestemp", "type": "uint256" } ], - "name": "AccrueInterest", - "type": "event" + "name": "SwapDeadlineExpire", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, "internalType": "address", - "name": "spender", + "name": "vToken", "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" } ], - "name": "Approval", - "type": "event" + "name": "VTokenNotListed", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "borrower", + "name": "underlying", "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "badDebtDelta", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "badDebtOld", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "badDebtNew", - "type": "uint256" } ], - "name": "BadDebtIncreased", - "type": "event" + "name": "VTokenUnderlyingInvalid", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "uint256", - "name": "badDebtOld", - "type": "uint256" + "internalType": "address", + "name": "expectedAdddress", + "type": "address" }, { - "indexed": false, - "internalType": "uint256", - "name": "badDebtNew", - "type": "uint256" + "internalType": "address", + "name": "passedAddress", + "type": "address" } ], - "name": "BadDebtRecovered", - "type": "event" + "name": "WrongAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" }, { "anonymous": false, @@ -38164,29 +37542,17 @@ { "indexed": true, "internalType": "address", - "name": "borrower", + "name": "previousOwner", "type": "address" }, { - "indexed": false, - "internalType": "uint256", - "name": "borrowAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "accountBorrows", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "totalBorrows", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" } ], - "name": "Borrow", + "name": "OwnershipTransferStarted", "type": "event" }, { @@ -38195,36 +37561,17 @@ { "indexed": true, "internalType": "address", - "name": "payer", + "name": "previousOwner", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "borrower", + "name": "newOwner", "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - } - ], - "name": "HealBorrow", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" } ], - "name": "Initialized", + "name": "OwnershipTransferred", "type": "event" }, { @@ -38233,35 +37580,23 @@ { "indexed": true, "internalType": "address", - "name": "liquidator", + "name": "swapper", "type": "address" }, { "indexed": true, - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "indexed": true, - "internalType": "address", - "name": "vTokenCollateral", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "seizeTokens", - "type": "uint256" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "LiquidateBorrow", + "name": "SwapBnbForTokens", "type": "event" }, { @@ -38270,48 +37605,42 @@ { "indexed": true, "internalType": "address", - "name": "minter", + "name": "swapper", "type": "address" }, { - "indexed": false, - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "mintTokens", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "accountBalance", - "type": "uint256" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "Mint", + "name": "SwapBnbForTokensAtSupportingFee", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "oldAccessControlManager", + "name": "swapper", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAccessControlManager", - "type": "address" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "NewAccessControlManager", + "name": "SwapTokensForBnb", "type": "event" }, { @@ -38319,18 +37648,18 @@ "inputs": [ { "indexed": true, - "internalType": "contract ComptrollerInterface", - "name": "oldComptroller", + "internalType": "address", + "name": "swapper", "type": "address" }, { "indexed": true, - "internalType": "contract ComptrollerInterface", - "name": "newComptroller", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "NewComptroller", + "name": "SwapTokensForBnbAtSupportingFee", "type": "event" }, { @@ -38338,37 +37667,43 @@ "inputs": [ { "indexed": true, - "internalType": "contract InterestRateModel", - "name": "oldInterestRateModel", + "internalType": "address", + "name": "swapper", "type": "address" }, { "indexed": true, - "internalType": "contract InterestRateModel", - "name": "newInterestRateModel", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "NewMarketInterestRateModel", + "name": "SwapTokensForTokens", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "uint256", - "name": "oldProtocolSeizeShareMantissa", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "swapper", + "type": "address" }, { - "indexed": false, - "internalType": "uint256", - "name": "newProtocolSeizeShareMantissa", - "type": "uint256" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "NewProtocolSeizeShare", + "name": "SwapTokensForTokensAtSupportingFee", "type": "event" }, { @@ -38377,36 +37712,23 @@ { "indexed": true, "internalType": "address", - "name": "oldProtocolShareReserve", + "name": "token", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newProtocolShareReserve", + "name": "to", "type": "address" - } - ], - "name": "NewProtocolShareReserve", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldReserveFactorMantissa", - "type": "uint256" }, { "indexed": false, "internalType": "uint256", - "name": "newReserveFactorMantissa", + "name": "sweepAmount", "type": "uint256" } ], - "name": "NewReserveFactor", + "name": "SweepToken", "type": "event" }, { @@ -38415,221 +37737,166 @@ { "indexed": true, "internalType": "address", - "name": "oldShortfall", + "name": "oldAddress", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newShortfall", + "name": "newAddress", "type": "address" } ], - "name": "NewShortfallContract", + "name": "VBNBAddressUpdated", "type": "event" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, + "inputs": [], + "name": "WBNB", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "", "type": "address" } ], - "name": "OwnershipTransferStarted", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "comptrollerAddress", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "", "type": "address" - }, + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "", "type": "address" } ], - "name": "OwnershipTransferred", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "redeemer", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "redeemAmount", + "name": "reserveIn", "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "redeemTokens", + "name": "reserveOut", "type": "uint256" - }, + } + ], + "name": "getAmountIn", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "accountBalance", + "name": "amountIn", "type": "uint256" } ], - "name": "Redeem", - "type": "event" + "stateMutability": "pure", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "payer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "indexed": false, "internalType": "uint256", - "name": "repayAmount", + "name": "amountIn", "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "accountBorrows", + "name": "reserveIn", "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "totalBorrows", + "name": "reserveOut", "type": "uint256" } ], - "name": "RepayBorrow", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "benefactor", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "addAmount", - "type": "uint256" - }, + "name": "getAmountOut", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "newTotalReserves", + "name": "amountOut", "type": "uint256" } ], - "name": "ReservesAdded", - "type": "event" + "stateMutability": "pure", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "admin", - "type": "address" - }, - { - "indexed": false, "internalType": "uint256", - "name": "reduceAmount", + "name": "amountOut", "type": "uint256" }, { - "indexed": false, - "internalType": "uint256", - "name": "newTotalReserves", - "type": "uint256" + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "ReservesReduced", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "getAmountsIn", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "SweepToken", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, "internalType": "uint256", - "name": "amount", + "name": "amountIn", "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [], - "name": "NO_ERROR", + "name": "getAmountsOut", "outputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "stateMutability": "view", @@ -38637,17 +37904,10 @@ }, { "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "accessControlManager", + "name": "owner", "outputs": [ { - "internalType": "contract IAccessControlManagerV8", + "internalType": "address", "name": "", "type": "address" } @@ -38657,39 +37917,62 @@ }, { "inputs": [], - "name": "accrualBlockNumber", + "name": "pendingOwner", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [], - "name": "accrueInterest", + "inputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", + "type": "uint256" + } + ], + "name": "quote", "outputs": [ { "internalType": "uint256", - "name": "", + "name": "amountB", "type": "uint256" } ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "addAmount", - "type": "uint256" + "internalType": "address", + "name": "_vBNBAddress", + "type": "address" } ], - "name": "addReserves", + "name": "setVBNBAddress", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -38697,396 +37980,481 @@ { "inputs": [ { - "internalType": "address", - "name": "owner", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "internalType": "address", - "name": "spender", + "name": "to", "type": "address" - } - ], - "name": "allowance", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "swapBNBForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "spender", + "name": "vTokenAddress", "type": "address" }, { "internalType": "uint256", - "name": "amount", + "name": "amountOut", "type": "uint256" - } - ], - "name": "approve", - "outputs": [ + }, { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "badDebt", - "outputs": [ + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapBNBForExactTokensAndRepay", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { "inputs": [ + { + "internalType": "address", + "name": "vTokenAddress", + "type": "address" + }, { "internalType": "uint256", - "name": "recoveredAmount_", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "name": "badDebtRecovered", + "name": "swapBNBForExactTokensAndSupply", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "owner", + "name": "vTokenAddress", "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapBNBForFullTokenDebtAndRepay", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "owner", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "balanceOfUnderlying", + "name": "swapExactBNBForTokens", "outputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, { "inputs": [ + { + "internalType": "address", + "name": "vTokenAddress", + "type": "address" + }, { "internalType": "uint256", - "name": "borrowAmount", + "name": "amountOutMin", "type": "uint256" - } - ], - "name": "borrow", - "outputs": [ + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "nonpayable", + "name": "swapExactBNBForTokensAndRepay", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "account", + "name": "vTokenAddress", "type": "address" - } - ], - "name": "borrowBalanceCurrent", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "nonpayable", + "name": "swapExactBNBForTokensAndRepayAtSupportingFee", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "account", + "name": "vTokenAddress", "type": "address" - } - ], - "name": "borrowBalanceStored", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "borrowIndex", - "outputs": [ + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactBNBForTokensAndSupply", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { - "inputs": [], - "name": "borrowRatePerBlock", - "outputs": [ + "inputs": [ + { + "internalType": "address", + "name": "vTokenAddress", + "type": "address" + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactBNBForTokensAndSupplyAtSupportingFee", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { - "inputs": [], - "name": "comptroller", - "outputs": [ + "inputs": [ { - "internalType": "contract ComptrollerInterface", - "name": "", + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", + "name": "swapExactBNBForTokensAtSupportingFee", "outputs": [ { - "internalType": "uint8", - "name": "", - "type": "uint8" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "payable", "type": "function" }, { "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "spender", + "name": "to", "type": "address" }, { "internalType": "uint256", - "name": "subtractedValue", + "name": "deadline", "type": "uint256" } ], - "name": "decreaseAllowance", + "name": "swapExactTokensForBNB", "outputs": [ { - "internalType": "bool", - "name": "", - "type": "bool" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "exchangeRateCurrent", - "outputs": [ + "inputs": [ { "internalType": "uint256", - "name": "", + "name": "amountIn", "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "exchangeRateStored", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactTokensForBNBAndRepay", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "liquidator", - "type": "address" - }, - { - "internalType": "address", - "name": "borrower", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { "internalType": "uint256", - "name": "repayAmount", + "name": "amountOutMin", "type": "uint256" }, { - "internalType": "contract VTokenInterface", - "name": "vTokenCollateral", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "internalType": "bool", - "name": "skipLiquidityCheck", - "type": "bool" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "forceLiquidateBorrow", + "name": "swapExactTokensForBNBAndRepayAtSupportingFee", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getAccountSnapshot", - "outputs": [ { "internalType": "uint256", - "name": "error", + "name": "amountIn", "type": "uint256" }, { "internalType": "uint256", - "name": "vTokenBalance", + "name": "amountOutMin", "type": "uint256" }, { - "internalType": "uint256", - "name": "borrowBalance", - "type": "uint256" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "internalType": "uint256", - "name": "exchangeRate", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactTokensForBNBAndSupply", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "getCash", - "outputs": [ + "inputs": [ { "internalType": "uint256", - "name": "", + "name": "amountIn", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ + }, { - "internalType": "address", - "name": "payer", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" }, { - "internalType": "address", - "name": "borrower", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "internalType": "uint256", - "name": "repayAmount", + "name": "deadline", "type": "uint256" } ], - "name": "healBorrow", + "name": "swapExactTokensForBNBAndSupplyAtSupportingFee", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "spender", + "name": "to", "type": "address" }, { "internalType": "uint256", - "name": "addedValue", + "name": "deadline", "type": "uint256" } ], - "name": "increaseAllowance", + "name": "swapExactTokensForBNBAtSupportingFee", "outputs": [ { - "internalType": "bool", - "name": "", - "type": "bool" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" } ], "stateMutability": "nonpayable", @@ -39094,150 +38462,73 @@ }, { "inputs": [ - { - "internalType": "address", - "name": "underlying_", - "type": "address" - }, - { - "internalType": "contract ComptrollerInterface", - "name": "comptroller_", - "type": "address" - }, - { - "internalType": "contract InterestRateModel", - "name": "interestRateModel_", - "type": "address" - }, { "internalType": "uint256", - "name": "initialExchangeRateMantissa_", + "name": "amountIn", "type": "uint256" }, { - "internalType": "string", - "name": "name_", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol_", - "type": "string" - }, - { - "internalType": "uint8", - "name": "decimals_", - "type": "uint8" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" }, { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "internalType": "address", - "name": "accessControlManager_", + "name": "to", "type": "address" }, - { - "components": [ - { - "internalType": "address", - "name": "shortfall", - "type": "address" - }, - { - "internalType": "address payable", - "name": "protocolShareReserve", - "type": "address" - } - ], - "internalType": "struct VTokenInterface.RiskManagementInit", - "name": "riskManagement", - "type": "tuple" - }, { "internalType": "uint256", - "name": "reserveFactorMantissa_", + "name": "deadline", "type": "uint256" } ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "interestRateModel", - "outputs": [ - { - "internalType": "contract InterestRateModel", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isVToken", + "name": "swapExactTokensForTokens", "outputs": [ { - "internalType": "bool", - "name": "", - "type": "bool" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "pure", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "borrower", + "name": "vTokenAddress", "type": "address" }, { "internalType": "uint256", - "name": "repayAmount", + "name": "amountIn", "type": "uint256" }, - { - "internalType": "contract VTokenInterface", - "name": "vTokenCollateral", - "type": "address" - } - ], - "name": "liquidateBorrow", - "outputs": [ { "internalType": "uint256", - "name": "", + "name": "amountOutMin", "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, { - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [ + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], + "name": "swapExactTokensForTokensAndRepay", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -39245,145 +38536,97 @@ "inputs": [ { "internalType": "address", - "name": "minter", + "name": "vTokenAddress", "type": "address" }, { "internalType": "uint256", - "name": "mintAmount", + "name": "amountIn", "type": "uint256" - } - ], - "name": "mintBehalf", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ + }, { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactTokensForTokensAndRepayAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "vTokenAddress", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "protocolSeizeShareMantissa", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountIn", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "protocolShareReserve", - "outputs": [ - { - "internalType": "address payable", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ + }, { "internalType": "uint256", - "name": "redeemTokens", + "name": "amountOutMin", "type": "uint256" - } - ], - "name": "redeem", - "outputs": [ + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], + "name": "swapExactTokensForTokensAndSupply", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "address", + "name": "vTokenAddress", + "type": "address" + }, { "internalType": "uint256", - "name": "redeemAmount", + "name": "amountIn", "type": "uint256" - } - ], - "name": "redeemUnderlying", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "reduceAmount", + "name": "deadline", "type": "uint256" } ], - "name": "reduceReserves", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", + "name": "swapExactTokensForTokensAndSupplyAtSupportingFee", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -39392,39 +38635,35 @@ "inputs": [ { "internalType": "uint256", - "name": "repayAmount", + "name": "amountIn", "type": "uint256" - } - ], - "name": "repayBorrow", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "borrower", + "name": "to", "type": "address" }, { "internalType": "uint256", - "name": "repayAmount", + "name": "deadline", "type": "uint256" } ], - "name": "repayBorrowBehalf", + "name": "swapExactTokensForTokensAtSupportingFee", "outputs": [ { "internalType": "uint256", - "name": "", + "name": "swapAmount", "type": "uint256" } ], @@ -39432,63 +38671,68 @@ "type": "function" }, { - "inputs": [], - "name": "reserveFactorMantissa", - "outputs": [ + "inputs": [ { "internalType": "uint256", - "name": "", + "name": "amountOut", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ + }, { - "internalType": "address", - "name": "liquidator", - "type": "address" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "internalType": "address", - "name": "borrower", + "name": "to", "type": "address" }, { "internalType": "uint256", - "name": "seizeTokens", + "name": "deadline", "type": "uint256" } ], - "name": "seize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "name": "swapTokensForExactBNB", + "outputs": [ { - "internalType": "address", - "name": "accessControlManager_", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "setAccessControlManager", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "contract InterestRateModel", - "name": "newInterestRateModel", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "setInterestRateModel", + "name": "swapTokensForExactBNBAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -39497,11 +38741,26 @@ "inputs": [ { "internalType": "uint256", - "name": "newProtocolSeizeShareMantissa_", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "name": "setProtocolSeizeShare", + "name": "swapTokensForExactBNBAndSupply", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -39509,196 +38768,179 @@ { "inputs": [ { - "internalType": "address payable", - "name": "protocolShareReserve_", + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", "type": "address" - } - ], - "name": "setProtocolShareReserve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, { "internalType": "uint256", - "name": "newReserveFactorMantissa", + "name": "deadline", "type": "uint256" } ], - "name": "setReserveFactor", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "name": "swapTokensForExactTokens", + "outputs": [ { - "internalType": "address", - "name": "shortfall_", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "setShortfallContract", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "shortfall", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "vTokenAddress", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "supplyRatePerBlock", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOut", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ + }, { - "internalType": "contract IERC20Upgradeable", - "name": "token", - "type": "address" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "sweepToken", + "name": "swapTokensForExactTokensAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "symbol", - "outputs": [ + "inputs": [ { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalBorrows", - "outputs": [ + "internalType": "address", + "name": "vTokenAddress", + "type": "address" + }, { "internalType": "uint256", - "name": "", + "name": "amountOut", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalBorrowsCurrent", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], + "name": "swapTokensForExactTokensAndSupply", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "totalReserves", - "outputs": [ + "inputs": [ { "internalType": "uint256", - "name": "", + "name": "amountInMax", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapTokensForFullBNBDebtAndRepay", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "dst", + "name": "vTokenAddress", "type": "address" }, { "internalType": "uint256", - "name": "amount", + "name": "amountInMax", "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ + }, { - "internalType": "bool", - "name": "", - "type": "bool" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], + "name": "swapTokensForFullTokenDebtAndRepay", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "src", + "internalType": "contract IERC20", + "name": "token", "type": "address" }, { "internalType": "address", - "name": "dst", + "name": "to", "type": "address" }, { "internalType": "uint256", - "name": "amount", + "name": "sweepAmount", "type": "uint256" } ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], + "name": "sweepToken", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -39717,7 +38959,7 @@ }, { "inputs": [], - "name": "underlying", + "name": "vBNBAddress", "outputs": [ { "internalType": "address", @@ -39727,341 +38969,290 @@ ], "stateMutability": "view", "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" } ] }, - "VToken_vALPACA_DeFi": { - "address": "0xb7caC5Ef82cb7f9197ee184779bdc52c5490C02a", + "SwapRouter_LiquidStakedBNB": { + "address": "0xb16792E90d6478DaBbd0144e13f41CeA21ACE116", "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "WBNB_", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "factory_", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "_comptrollerAddress", "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "_vBNBAddress", "type": "address" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "nonpayable", + "type": "constructor" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountMax", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" + "name": "ExcessiveInputAmount", + "type": "error" }, { - "stateMutability": "payable", - "type": "fallback" + "inputs": [], + "name": "IdenticalAddresses", + "type": "error" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vANKR_DeFi": { - "address": "0xb677e080148368EeeE70fA3865d07E92c6500174", - "abi": [ { "inputs": [ { - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountIntMax", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "InputAmountAboveMaximum", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "sweepAmount", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "balance", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "InsufficientBalance", + "type": "error" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" + "inputs": [], + "name": "InsufficientInputAmount", + "type": "error" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" + "inputs": [], + "name": "InsufficientLiquidity", + "type": "error" }, { - "stateMutability": "payable", - "type": "fallback" + "inputs": [], + "name": "InsufficientOutputAmount", + "type": "error" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vBNBx_LiquidStakedBNB": { - "address": "0x644A149853E5507AdF3e682218b8AC86cdD62951", - "abi": [ + "inputs": [], + "name": "InvalidPath", + "type": "error" + }, { "inputs": [ { - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "OutputAmountBelowMinimum", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrantCheck", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "repayer", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "vToken", "type": "address" + }, + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "RepayError", + "type": "error" + }, + { + "inputs": [], + "name": "SafeApproveFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferBNBFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferFromFailed", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "supplier", "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "vToken", "type": "address" + }, + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "SupplyError", + "type": "error" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vBSW_DeFi": { - "address": "0x5e68913fbbfb91af30366ab1B21324410b49a308", - "abi": [ { "inputs": [ { - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "SwapAmountLessThanAmountOutMin", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "timestemp", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "SwapDeadlineExpire", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "vToken", "type": "address" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "VTokenNotListed", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "underlying", "type": "address" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "VTokenUnderlyingInvalid", + "type": "error" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vBTT_Tron": { - "address": "0x47793540757c6E6D84155B33cd8D9535CFdb9334", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "expectedAdddress", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "address", + "name": "passedAddress", + "type": "address" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "WrongAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" }, { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "previousAdmin", + "name": "previousOwner", "type": "address" }, { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "newAdmin", + "name": "newOwner", "type": "address" } ], - "name": "AdminChanged", + "name": "OwnershipTransferStarted", "type": "event" }, { @@ -40070,11 +39261,17 @@ { "indexed": true, "internalType": "address", - "name": "beacon", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", "type": "address" } ], - "name": "BeaconUpgraded", + "name": "OwnershipTransferred", "type": "event" }, { @@ -40083,59 +39280,67 @@ { "indexed": true, "internalType": "address", - "name": "implementation", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "Upgraded", + "name": "SwapBnbForTokens", "type": "event" }, { - "stateMutability": "payable", - "type": "fallback" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vFLOKI_GameFi": { - "address": "0xef470AbC365F88e4582D8027172a392C473A5B53", - "abi": [ - { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "beacon", + "name": "swapper", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "SwapBnbForTokensAtSupportingFee", + "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "previousAdmin", + "name": "swapper", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "AdminChanged", + "name": "SwapTokensForBnb", "type": "event" }, { @@ -40144,11 +39349,17 @@ { "indexed": true, "internalType": "address", - "name": "beacon", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "BeaconUpgraded", + "name": "SwapTokensForBnbAtSupportingFee", "type": "event" }, { @@ -40157,59 +39368,67 @@ { "indexed": true, "internalType": "address", - "name": "implementation", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "Upgraded", + "name": "SwapTokensForTokens", "type": "event" }, { - "stateMutability": "payable", - "type": "fallback" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vHAY_StableCoins": { - "address": "0x170d3b2da05cc2124334240fB34ad1359e34C562", - "abi": [ - { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "beacon", + "name": "swapper", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "SwapTokensForTokensAtSupportingFee", + "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "previousAdmin", + "name": "token", "type": "address" }, { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "newAdmin", + "name": "to", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sweepAmount", + "type": "uint256" } ], - "name": "AdminChanged", + "name": "SweepToken", "type": "event" }, { @@ -40218,991 +39437,1238 @@ { "indexed": true, "internalType": "address", - "name": "beacon", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", "type": "address" } ], - "name": "BeaconUpgraded", + "name": "VBNBAddressUpdated", "type": "event" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "WBNB", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "", "type": "address" } ], - "name": "Upgraded", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "stateMutability": "payable", - "type": "fallback" + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vNFT_Tron": { - "address": "0x67cD2A8aFF63C7eBbC7A601506f9Dbb8557d6547", - "abi": [ - { - "inputs": [ + "inputs": [], + "name": "comptrollerAddress", + "outputs": [ { "internalType": "address", - "name": "beacon", + "name": "", "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" } ], - "stateMutability": "payable", - "type": "constructor" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, + "inputs": [], + "name": "factory", + "outputs": [ { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "", "type": "address" } ], - "name": "AdminChanged", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "getAmountIn", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "stateMutability": "pure", + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vRACA_GameFi": { - "address": "0x1958035231E125830bA5d17D168cEa07Bb42184a", - "abi": [ { "inputs": [ { - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "AdminChanged", - "type": "event" + "name": "getAmountsIn", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "getAmountsOut", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "owner", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "", "type": "address" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "stateMutability": "view", + "type": "function" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vTRX_Tron": { - "address": "0x410286c43a525E1DCC7468a9B091C111C8324cd1", - "abi": [ - { - "inputs": [ + "inputs": [], + "name": "pendingOwner", + "outputs": [ { "internalType": "address", - "name": "beacon", + "name": "", "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" } ], - "stateMutability": "payable", - "type": "constructor" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountA", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "quote", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountB", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "_vBNBAddress", "type": "address" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "setVBNBAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDD_DeFi": { - "address": "0xa109DE0abaeefC521Ec29D89eA42E64F37A6882E", - "abi": [ { "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "beacon", + "name": "to", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapBNBForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "stateMutability": "payable", - "type": "constructor" + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "vTokenAddress", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "swapBNBForExactTokensAndRepay", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { + "name": "swapBNBForExactTokensAndSupply", + "outputs": [], "stateMutability": "payable", - "type": "fallback" + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDD_GameFi": { - "address": "0xdeDf3B2bcF25d0023115fd71a0F8221C91C92B1a", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], + "name": "swapBNBForFullTokenDebtAndRepay", + "outputs": [], "stateMutability": "payable", - "type": "constructor" + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "swapExactBNBForTokens", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { + "name": "swapExactBNBForTokensAndRepay", + "outputs": [], "stateMutability": "payable", - "type": "fallback" + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDD_LiquidStakedBNB": { - "address": "0xD5b20708d8f0FcA52cb609938D0594C4e32E5DaD", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], + "name": "swapExactBNBForTokensAndRepayAtSupportingFee", + "outputs": [], "stateMutability": "payable", - "type": "constructor" + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "vTokenAddress", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "swapExactBNBForTokensAndSupply", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { + "name": "swapExactBNBForTokensAndSupplyAtSupportingFee", + "outputs": [], "stateMutability": "payable", - "type": "fallback" + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDD_StableCoins": { - "address": "0x899dDf81DfbbF5889a16D075c352F2b959Dd24A4", - "abi": [ { "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "beacon", + "name": "to", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactBNBForTokensAtSupportingFee", + "outputs": [ + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" } ], "stateMutability": "payable", - "type": "constructor" + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "swapExactTokensForBNB", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "swapExactTokensForBNBAndRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDD_Tron": { - "address": "0xD804F74fe21290d213c46610ab171f7c2EeEBDE7", - "abi": [ { "inputs": [ { - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "swapExactTokensForBNBAndRepayAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "swapExactTokensForBNBAndSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "swapExactTokensForBNBAndSupplyAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { "internalType": "address", - "name": "implementation", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "swapExactTokensForBNBAtSupportingFee", + "outputs": [ + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDT_DeFi": { - "address": "0x80CC30811e362aC9aB857C3d7875CbcCc0b65750", - "abi": [ { "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "beacon", + "name": "to", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "swapExactTokensForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "vTokenAddress", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "swapExactTokensForTokensAndRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "swapExactTokensForTokensAndRepayAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "swapExactTokensForTokensAndSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDT_GameFi": { - "address": "0x0bFE4e0B8A2a096A27e5B18b078d25be57C08634", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "swapExactTokensForTokensAndSupplyAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "swapExactTokensForTokensAtSupportingFee", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { "internalType": "address", - "name": "implementation", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "swapTokensForExactBNB", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDT_LiquidStakedBNB": { - "address": "0x2197d02cC9cd1ad51317A0a85A656a0c82383A7c", - "abi": [ { "inputs": [ { - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "swapTokensForExactBNBAndRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "swapTokensForExactBNBAndSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { "internalType": "address", - "name": "beacon", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "swapTokensForExactTokens", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "stateMutability": "nonpayable", + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDT_StableCoins": { - "address": "0x3338988d0beb4419Acb8fE624218754053362D06", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "swapTokensForExactTokensAndRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "swapTokensForExactTokensAndSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "swapTokensForFullBNBDebtAndRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vUSDT_Tron": { - "address": "0x712774CBFFCBD60e9825871CcEFF2F917442b2c3", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "swapTokensForFullTokenDebtAndRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", + "internalType": "contract IERC20", + "name": "token", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "sweepAmount", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "newOwner", "type": "address" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "vBNBAddress", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "", "type": "address" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "stateMutability": "view", + "type": "function" }, { "stateMutability": "payable", @@ -41210,339 +40676,265 @@ } ] }, - "VToken_vWBNB_LiquidStakedBNB": { - "address": "0x231dED0Dfc99634e52EE1a1329586bc970d773b3", + "SwapRouter_StableCoins": { + "address": "0x8Ff3c0a74b4CBD4dFA3A35Cca756490bE351F936", "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "WBNB_", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "factory_", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "_comptrollerAddress", "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "_vBNBAddress", "type": "address" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "nonpayable", + "type": "constructor" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountMax", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" + "name": "ExcessiveInputAmount", + "type": "error" }, { - "stateMutability": "payable", - "type": "fallback" + "inputs": [], + "name": "IdenticalAddresses", + "type": "error" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vWIN_Tron": { - "address": "0xEe543D5de2Dbb5b07675Fc72831A2f1812428393", - "abi": [ { "inputs": [ { - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountIntMax", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "InputAmountAboveMaximum", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "sweepAmount", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "balance", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "InsufficientBalance", + "type": "error" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" + "inputs": [], + "name": "InsufficientInputAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientLiquidity", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientOutputAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPath", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" + "name": "OutputAmountBelowMinimum", + "type": "error" }, { - "stateMutability": "payable", - "type": "fallback" + "inputs": [], + "name": "ReentrantCheck", + "type": "error" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vankrBNB_DeFi": { - "address": "0xe507B30C41E9e375BCe05197c1e09fc9ee40c0f6", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "repayer", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "vToken", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "RepayError", + "type": "error" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" + "inputs": [], + "name": "SafeApproveFailed", + "type": "error" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" + "inputs": [], + "name": "SafeTransferBNBFailed", + "type": "error" }, { - "stateMutability": "payable", - "type": "fallback" + "inputs": [], + "name": "SafeTransferFailed", + "type": "error" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vankrBNB_LiquidStakedBNB": { - "address": "0x57a664Dd7f1dE19545fEE9c86C949e3BF43d6D47", - "abi": [ + "inputs": [], + "name": "SafeTransferFromFailed", + "type": "error" + }, { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "supplier", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "SupplyError", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "SwapAmountLessThanAmountOutMin", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestemp", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "SwapDeadlineExpire", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "vToken", "type": "address" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "VTokenNotListed", + "type": "error" }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "VToken_vstkBNB_LiquidStakedBNB": { - "address": "0x75aa42c832a8911B77219DbeBABBB40040d16987", - "abi": [ { "inputs": [ { "internalType": "address", - "name": "beacon", + "name": "underlying", "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "VTokenUnderlyingInvalid", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "expectedAdddress", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "passedAddress", "type": "address" } ], - "name": "AdminChanged", - "type": "event" + "name": "WrongAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" }, { "anonymous": false, @@ -41550,56 +40942,36 @@ { "indexed": true, "internalType": "address", - "name": "beacon", + "name": "previousOwner", "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { "indexed": true, "internalType": "address", - "name": "implementation", + "name": "newOwner", "type": "address" } ], - "name": "Upgraded", + "name": "OwnershipTransferStarted", "type": "event" }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "BinanceOracle": { - "address": "0xB58BFDCE610042311Dc0e034a80Cc7776c1D68f5", - "abi": [ { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "previousAdmin", + "name": "previousOwner", "type": "address" }, { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "newAdmin", + "name": "newOwner", "type": "address" } ], - "name": "AdminChanged", + "name": "OwnershipTransferred", "type": "event" }, { @@ -41608,11 +40980,23 @@ { "indexed": true, "internalType": "address", - "name": "beacon", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "BeaconUpgraded", + "name": "SwapBnbForTokens", "type": "event" }, { @@ -41621,110 +41005,86 @@ { "indexed": true, "internalType": "address", - "name": "implementation", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "Upgraded", + "name": "SwapBnbForTokensAtSupportingFee", "type": "event" }, { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "admin_", + "name": "swapper", "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ + }, { - "internalType": "address", - "name": "implementation_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { - "internalType": "address", - "name": "newImplementation", - "type": "address" + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "SwapTokensForBnb", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newImplementation", + "name": "swapper", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" + "name": "SwapTokensForBnbAtSupportingFee", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "sender", + "name": "swapper", "type": "address" }, { - "internalType": "address", - "name": "calledContract", - "type": "address" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "internalType": "string", - "name": "methodSignature", - "type": "string" - } - ], - "name": "Unauthorized", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "Initialized", + "name": "SwapTokensForTokens", "type": "event" }, { @@ -41732,37 +41092,43 @@ "inputs": [ { "indexed": true, - "internalType": "string", - "name": "asset", - "type": "string" + "internalType": "address", + "name": "swapper", + "type": "address" }, { - "indexed": false, - "internalType": "uint256", - "name": "maxStalePeriod", - "type": "uint256" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "MaxStalePeriodAdded", + "name": "SwapTokensForTokensAtSupportingFee", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "oldAccessControlManager", + "name": "token", "type": "address" }, { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "newAccessControlManager", + "name": "to", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sweepAmount", + "type": "uint256" } ], - "name": "NewAccessControlManager", + "name": "SweepToken", "type": "event" }, { @@ -41771,37 +41137,31 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "oldAddress", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "newAddress", "type": "address" } ], - "name": "OwnershipTransferStarted", + "name": "VBNBAddressUpdated", "type": "event" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, + "inputs": [], + "name": "WBNB", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "", "type": "address" } ], - "name": "OwnershipTransferred", - "type": "event" + "stateMutability": "view", + "type": "function" }, { "inputs": [], @@ -41812,10 +41172,10 @@ }, { "inputs": [], - "name": "accessControlManager", + "name": "comptrollerAddress", "outputs": [ { - "internalType": "contract IAccessControlManagerV8", + "internalType": "address", "name": "", "type": "address" } @@ -41825,7 +41185,7 @@ }, { "inputs": [], - "name": "getFeedRegistryAddress", + "name": "factory", "outputs": [ { "internalType": "address", @@ -41839,67 +41199,104 @@ { "inputs": [ { - "internalType": "address", - "name": "vToken", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" } ], - "name": "getUnderlyingPrice", + "name": "getAmountIn", "outputs": [ { "internalType": "uint256", - "name": "", + "name": "amountIn", "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "_sidRegistryAddress", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "internalType": "address", - "name": "_accessControlManager", - "type": "address" + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" } ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "pure", "type": "function" }, { "inputs": [ { - "internalType": "string", - "name": "", - "type": "string" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "maxStalePeriod", + "name": "getAmountsIn", "outputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [], - "name": "owner", + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsOut", "outputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "stateMutability": "view", @@ -41907,7 +41304,7 @@ }, { "inputs": [], - "name": "pendingOwner", + "name": "owner", "outputs": [ { "internalType": "address", @@ -41920,377 +41317,422 @@ }, { "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "name": "pendingOwner", + "outputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "", "type": "address" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "string", - "name": "symbol", - "type": "string" - }, { "internalType": "uint256", - "name": "_maxStalePeriod", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", "type": "uint256" } ], - "name": "setMaxStalePeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "sidRegistryAddress", + "name": "quote", "outputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "amountB", + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "newOwner", + "name": "_vBNBAddress", "type": "address" } ], - "name": "transferOwnership", + "name": "setVBNBAddress", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "vBnb", - "outputs": [ + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "vai", + "name": "swapBNBForExactTokens", "outputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "view", + "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "_logic", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "internalType": "bytes", - "name": "_data", - "type": "bytes" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], + "name": "swapBNBForExactTokensAndRepay", + "outputs": [], "stateMutability": "payable", - "type": "constructor" - } - ] - }, - "BinanceOracle_Implementation": { - "address": "0xCd64844CD0E8E34782cd0d1bF3E537bf7b474FAe", - "abi": [ + "type": "function" + }, { "inputs": [ { "internalType": "address", - "name": "vBnbAddress", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "address", - "name": "vaiAddress", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "constructor" + "name": "swapBNBForExactTokensAndSupply", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "sender", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "address", - "name": "calledContract", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Unauthorized", - "type": "error" + "name": "swapBNBForFullTokenDebtAndRepay", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, { - "indexed": true, - "internalType": "string", - "name": "asset", - "type": "string" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" }, { - "indexed": false, "internalType": "uint256", - "name": "maxStalePeriod", + "name": "deadline", "type": "uint256" } ], - "name": "MaxStalePeriodAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "oldAccessControlManager", - "type": "address" - }, + "name": "swapExactBNBForTokens", + "outputs": [ { - "indexed": false, - "internalType": "address", - "name": "newAccessControlManager", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "NewAccessControlManager", - "type": "event" + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "vTokenAddress", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferStarted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "acceptOwnership", + "name": "swapExactBNBForTokensAndRepay", "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "accessControlManager", - "outputs": [ - { - "internalType": "contract IAccessControlManagerV8", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", + "stateMutability": "payable", "type": "function" }, { - "inputs": [], - "name": "getFeedRegistryAddress", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactBNBForTokensAndRepayAtSupportingFee", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "vTokenAddress", "type": "address" - } - ], - "name": "getUnderlyingPrice", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactBNBForTokensAndSupply", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "_sidRegistryAddress", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "address", - "name": "_accessControlManager", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "initialize", + "name": "swapExactBNBForTokensAndSupplyAtSupportingFee", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, { "inputs": [ { - "internalType": "string", - "name": "", - "type": "string" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "maxStalePeriod", + "name": "swapExactBNBForTokensAtSupportingFee", "outputs": [ { "internalType": "uint256", - "name": "", + "name": "swapAmount", "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "payable", "type": "function" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", + "name": "swapExactTokensForBNB", "outputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "accessControlManager_", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "setAccessControlManager", + "name": "swapExactTokensForBNBAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -42298,171 +41740,195 @@ { "inputs": [ { - "internalType": "string", - "name": "symbol", - "type": "string" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { "internalType": "uint256", - "name": "_maxStalePeriod", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "name": "setMaxStalePeriod", + "name": "swapExactTokensForBNBAndRepayAtSupportingFee", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "sidRegistryAddress", - "outputs": [ + "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactTokensForBNBAndSupply", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "transferOwnership", + "name": "swapExactTokensForBNBAndSupplyAtSupportingFee", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "vBnb", - "outputs": [ + "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "vai", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ] - }, - "BinanceOracle_Proxy": { - "address": "0xB58BFDCE610042311Dc0e034a80Cc7776c1D68f5", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_logic", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" }, { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "to", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "swapExactTokensForBNBAtSupportingFee", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { "internalType": "address", - "name": "implementation", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", + "name": "swapExactTokensForTokens", "outputs": [ { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "implementation", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "implementation_", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], + "name": "swapExactTokensForTokensAndRepay", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -42470,11 +41936,31 @@ "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "upgradeTo", + "name": "swapExactTokensForTokensAndRepayAtSupportingFee", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -42483,99 +41969,141 @@ "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "upgradeToAndCall", + "name": "swapExactTokensForTokensAndSupply", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "BoundValidator": { - "address": "0x2842140e4Ad3a92e9af30e27e290300dd785076d", - "abi": [ - { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "vTokenAddress", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "swapExactTokensForTokensAndSupplyAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { "internalType": "address", - "name": "implementation", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", + "name": "swapExactTokensForTokensAtSupportingFee", "outputs": [ { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" } ], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "implementation", - "outputs": [ + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "implementation_", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactBNB", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "stateMutability": "nonpayable", @@ -42584,12 +42112,27 @@ { "inputs": [ { - "internalType": "address", - "name": "newImplementation", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "upgradeTo", + "name": "swapTokensForExactBNBAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -42597,203 +42140,226 @@ { "inputs": [ { - "internalType": "address", - "name": "newImplementation", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "upgradeToAndCall", + "name": "swapTokensForExactBNBAndSupply", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - }, { "inputs": [ { - "internalType": "address", - "name": "sender", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "internalType": "address", - "name": "calledContract", + "name": "to", "type": "address" }, { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Unauthorized", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ + "name": "swapTokensForExactTokens", + "outputs": [ { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "Initialized", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "oldAccessControlManager", + "name": "vTokenAddress", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAccessControlManager", - "type": "address" - } - ], - "name": "NewAccessControlManager", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferStarted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "OwnershipTransferred", - "type": "event" + "name": "swapTokensForExactTokensAndRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "asset", + "name": "vTokenAddress", "type": "address" }, { - "indexed": true, "internalType": "uint256", - "name": "upperBound", + "name": "amountOut", "type": "uint256" }, { - "indexed": true, "internalType": "uint256", - "name": "lowerBound", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "name": "ValidateConfigAdded", - "type": "event" + "name": "swapTokensForExactTokensAndSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "inputs": [], - "name": "BNB_ADDR", - "outputs": [ + "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptOwnership", + "name": "swapTokensForFullBNBDebtAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "accessControlManager", - "outputs": [ + "inputs": [ { - "internalType": "contract IAccessControlManagerV8", - "name": "", + "internalType": "address", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", + "name": "swapTokensForFullTokenDebtAndRepay", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, { "internalType": "address", - "name": "accessControlManager_", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "sweepAmount", + "type": "uint256" } ], - "name": "initialize", + "name": "sweepToken", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "newOwner", "type": "address" } ], - "stateMutability": "view", + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "pendingOwner", + "name": "vBNBAddress", "outputs": [ { "internalType": "address", @@ -42805,276 +42371,270 @@ "type": "function" }, { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "SwapRouter_Tron": { + "address": "0x1D8cA5AFB88F07489786A3d2E0FF50F3F9314d97", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "WBNB_", + "type": "address" + }, + { + "internalType": "address", + "name": "factory_", + "type": "address" + }, + { + "internalType": "address", + "name": "_comptrollerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_vBNBAddress", "type": "address" } ], - "name": "setAccessControlManager", - "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "constructor" }, { "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "upperBoundRatio", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lowerBoundRatio", - "type": "uint256" - } - ], - "internalType": "struct BoundValidator.ValidateConfig", - "name": "config", - "type": "tuple" + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountMax", + "type": "uint256" } ], - "name": "setValidateConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "ExcessiveInputAmount", + "type": "error" + }, + { + "inputs": [], + "name": "IdenticalAddresses", + "type": "error" }, { "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "upperBoundRatio", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lowerBoundRatio", - "type": "uint256" - } - ], - "internalType": "struct BoundValidator.ValidateConfig[]", - "name": "configs", - "type": "tuple[]" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountIntMax", + "type": "uint256" } ], - "name": "setValidateConfigs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "InputAmountAboveMaximum", + "type": "error" }, { "inputs": [ { - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "sweepAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" } ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "InsufficientBalance", + "type": "error" }, { "inputs": [], - "name": "vBnb", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "name": "InsufficientInputAmount", + "type": "error" }, { "inputs": [], - "name": "vai", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "name": "InsufficientLiquidity", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientOutputAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPath", + "type": "error" }, { "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "validateConfigs", - "outputs": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, { "internalType": "uint256", - "name": "upperBoundRatio", + "name": "amountOut", "type": "uint256" }, { "internalType": "uint256", - "name": "lowerBoundRatio", + "name": "amountOutMin", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "OutputAmountBelowMinimum", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrantCheck", + "type": "error" }, { "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "repayer", "type": "address" }, { - "internalType": "uint256", - "name": "reportedPrice", - "type": "uint256" + "internalType": "address", + "name": "vToken", + "type": "address" }, { "internalType": "uint256", - "name": "anchorPrice", + "name": "errorCode", "type": "uint256" } ], - "name": "validatePriceWithAnchorPrice", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" + "name": "RepayError", + "type": "error" + }, + { + "inputs": [], + "name": "SafeApproveFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferBNBFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferFromFailed", + "type": "error" }, { "inputs": [ { "internalType": "address", - "name": "_logic", + "name": "supplier", "type": "address" }, { "internalType": "address", - "name": "admin_", + "name": "vToken", "type": "address" }, { - "internalType": "bytes", - "name": "_data", - "type": "bytes" + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" - } - ] - }, - "BoundValidator_Implementation": { - "address": "0x4915F67a57FDcbA22535F0F021D64b66b095d026", - "abi": [ + "name": "SupplyError", + "type": "error" + }, { "inputs": [ { - "internalType": "address", - "name": "vBnbAddress", - "type": "address" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" }, { - "internalType": "address", - "name": "vaiAddress", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "constructor" + "name": "SwapAmountLessThanAmountOutMin", + "type": "error" }, { "inputs": [ { - "internalType": "address", - "name": "sender", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" }, + { + "internalType": "uint256", + "name": "timestemp", + "type": "uint256" + } + ], + "name": "SwapDeadlineExpire", + "type": "error" + }, + { + "inputs": [ { "internalType": "address", - "name": "calledContract", + "name": "vToken", "type": "address" - }, - { - "internalType": "string", - "name": "methodSignature", - "type": "string" } ], - "name": "Unauthorized", + "name": "VTokenNotListed", "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" + "internalType": "address", + "name": "underlying", + "type": "address" } ], - "name": "Initialized", - "type": "event" + "name": "VTokenUnderlyingInvalid", + "type": "error" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "oldAccessControlManager", + "name": "expectedAdddress", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAccessControlManager", + "name": "passedAddress", "type": "address" } ], - "name": "NewAccessControlManager", - "type": "event" + "name": "WrongAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" }, { "anonymous": false, @@ -43120,193 +42680,199 @@ { "indexed": true, "internalType": "address", - "name": "asset", + "name": "swapper", "type": "address" }, { "indexed": true, - "internalType": "uint256", - "name": "upperBound", - "type": "uint256" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "indexed": true, - "internalType": "uint256", - "name": "lowerBound", - "type": "uint256" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "ValidateConfigAdded", + "name": "SwapBnbForTokens", "type": "event" }, { - "inputs": [], - "name": "BNB_ADDR", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "SwapBnbForTokensAtSupportingFee", + "type": "event" }, { - "inputs": [], - "name": "accessControlManager", - "outputs": [ + "anonymous": false, + "inputs": [ { - "internalType": "contract IAccessControlManagerV8", - "name": "", + "indexed": true, + "internalType": "address", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "view", - "type": "function" + "name": "SwapTokensForBnb", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "accessControlManager_", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "SwapTokensForBnbAtSupportingFee", + "type": "event" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "swapper", "type": "address" + }, + { + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "view", - "type": "function" + "name": "SwapTokensForTokens", + "type": "event" }, { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "swapper", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, { - "internalType": "address", - "name": "accessControlManager_", - "type": "address" + "indexed": true, + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "SwapTokensForTokensAtSupportingFee", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "upperBoundRatio", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lowerBoundRatio", - "type": "uint256" - } - ], - "internalType": "struct BoundValidator.ValidateConfig", - "name": "config", - "type": "tuple" + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sweepAmount", + "type": "uint256" } ], - "name": "setValidateConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "SweepToken", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "upperBoundRatio", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lowerBoundRatio", - "type": "uint256" - } - ], - "internalType": "struct BoundValidator.ValidateConfig[]", - "name": "configs", - "type": "tuple[]" + "indexed": true, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" } ], - "name": "setValidateConfigs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "VBNBAddressUpdated", + "type": "event" }, { - "inputs": [ + "inputs": [], + "name": "WBNB", + "outputs": [ { "internalType": "address", - "name": "newOwner", + "name": "", "type": "address" } ], - "name": "transferOwnership", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "vBnb", + "name": "comptrollerAddress", "outputs": [ { "internalType": "address", @@ -43319,7 +42885,7 @@ }, { "inputs": [], - "name": "vai", + "name": "factory", "outputs": [ { "internalType": "address", @@ -43333,159 +42899,168 @@ { "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "validateConfigs", - "outputs": [ - { - "internalType": "address", - "name": "asset", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { "internalType": "uint256", - "name": "upperBoundRatio", + "name": "reserveIn", "type": "uint256" }, { "internalType": "uint256", - "name": "lowerBoundRatio", + "name": "reserveOut", "type": "uint256" } ], - "stateMutability": "view", + "name": "getAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "pure", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "vToken", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { "internalType": "uint256", - "name": "reportedPrice", + "name": "reserveIn", "type": "uint256" }, { "internalType": "uint256", - "name": "anchorPrice", + "name": "reserveOut", "type": "uint256" } ], - "name": "validatePriceWithAnchorPrice", + "name": "getAmountOut", "outputs": [ { - "internalType": "bool", - "name": "", - "type": "bool" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "pure", "type": "function" - } - ] - }, - "BoundValidator_Proxy": { - "address": "0x2842140e4Ad3a92e9af30e27e290300dd785076d", - "abi": [ + }, { "inputs": [ { - "internalType": "address", - "name": "_logic", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "internalType": "address", - "name": "admin_", - "type": "address" - }, + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsIn", + "outputs": [ { - "internalType": "bytes", - "name": "_data", - "type": "bytes" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "payable", - "type": "constructor" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" } ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "getAmountsOut", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "owner", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "", "type": "address" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "admin", + "name": "pendingOwner", "outputs": [ { "internalType": "address", - "name": "admin_", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [], - "name": "implementation", + "inputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", + "type": "uint256" + } + ], + "name": "quote", "outputs": [ { - "internalType": "address", - "name": "implementation_", - "type": "address" + "internalType": "uint256", + "name": "amountB", + "type": "uint256" } ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -43493,420 +43068,534 @@ "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "_vBNBAddress", "type": "address" } ], - "name": "upgradeTo", + "name": "setVBNBAddress", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "newImplementation", + "name": "to", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapBNBForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "upgradeToAndCall", - "outputs": [], "stateMutability": "payable", "type": "function" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "ChainlinkOracle": { - "address": "0xCeA29f1266e880A1482c06eD656cD08C148BaA32", - "abi": [ - { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "vTokenAddress", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "swapBNBForExactTokensAndRepay", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "swapBNBForExactTokensAndSupply", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { + "name": "swapBNBForFullTokenDebtAndRepay", + "outputs": [], "stateMutability": "payable", - "type": "fallback" + "type": "function" }, { - "inputs": [], - "name": "admin", - "outputs": [ + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "admin_", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", + "name": "swapExactBNBForTokens", "outputs": [ { - "internalType": "address", - "name": "implementation_", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "vTokenAddress", "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "upgradeTo", + "name": "swapExactBNBForTokensAndRepay", "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "upgradeToAndCall", + "name": "swapExactBNBForTokensAndRepayAtSupportingFee", "outputs": [], "stateMutability": "payable", "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - }, { "inputs": [ { "internalType": "address", - "name": "sender", + "name": "vTokenAddress", "type": "address" }, { - "internalType": "address", - "name": "calledContract", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" }, { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "Unauthorized", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" + "name": "swapExactBNBForTokensAndSupply", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "oldAccessControlManager", + "name": "vTokenAddress", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAccessControlManager", - "type": "address" - } - ], - "name": "NewAccessControlManager", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "OwnershipTransferStarted", - "type": "event" + "name": "swapExactBNBForTokensAndSupplyAtSupportingFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { - "indexed": true, "internalType": "address", - "name": "asset", + "name": "to", "type": "address" }, { - "indexed": false, "internalType": "uint256", - "name": "previousPriceMantissa", + "name": "deadline", "type": "uint256" - }, + } + ], + "name": "swapExactBNBForTokensAtSupportingFee", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "newPriceMantissa", + "name": "swapAmount", "type": "uint256" } ], - "name": "PricePosted", - "type": "event" + "stateMutability": "payable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": false, "internalType": "address", - "name": "feed", + "name": "to", "type": "address" }, { - "indexed": false, "internalType": "uint256", - "name": "maxStalePeriod", + "name": "deadline", "type": "uint256" } ], - "name": "TokenConfigAdded", - "type": "event" - }, - { - "inputs": [], - "name": "BNB_ADDR", + "name": "swapExactTokensForBNB", "outputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "accessControlManager", - "outputs": [ + "inputs": [ { - "internalType": "contract IAccessControlManagerV8", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactTokensForBNBAndRepay", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "vToken", - "type": "address" - } - ], - "name": "getUnderlyingPrice", - "outputs": [ + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, { "internalType": "uint256", - "name": "", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactTokensForBNBAndRepayAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "accessControlManager_", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "initialize", + "name": "swapExactTokensForBNBAndSupply", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactTokensForBNBAndSupplyAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "prices", + "name": "swapExactTokensForBNBAtSupportingFee", "outputs": [ { "internalType": "uint256", - "name": "", + "name": "swapAmount", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "accessControlManager_", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "name": "setAccessControlManager", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -43914,46 +43603,31 @@ "inputs": [ { "internalType": "address", - "name": "asset", + "name": "vTokenAddress", "type": "address" }, { "internalType": "uint256", - "name": "price", + "name": "amountIn", "type": "uint256" - } - ], - "name": "setDirectPrice", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address", - "name": "feed", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxStalePeriod", - "type": "uint256" - } - ], - "internalType": "struct ChainlinkOracle.TokenConfig", - "name": "tokenConfig", - "type": "tuple" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "setTokenConfig", + "name": "swapExactTokensForTokensAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -43961,29 +43635,32 @@ { "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address", - "name": "feed", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxStalePeriod", - "type": "uint256" - } - ], - "internalType": "struct ChainlinkOracle.TokenConfig[]", - "name": "tokenConfigs_", - "type": "tuple[]" + "internalType": "address", + "name": "vTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "setTokenConfigs", + "name": "swapExactTokensForTokensAndRepayAtSupportingFee", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -43991,17 +43668,32 @@ { "inputs": [ { - "internalType": "contract VBep20Interface", - "name": "vToken", + "internalType": "address", + "name": "vTokenAddress", "type": "address" }, { "internalType": "uint256", - "name": "underlyingPriceMantissa", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "name": "setUnderlyingPrice", + "name": "swapExactTokensForTokensAndSupply", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -44010,366 +43702,237 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "vTokenAddress", "type": "address" - } - ], - "name": "tokenConfigs", - "outputs": [ + }, { - "internalType": "address", - "name": "asset", - "type": "address" + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" }, { - "internalType": "address", - "name": "feed", - "type": "address" + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { "internalType": "uint256", - "name": "maxStalePeriod", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", + "name": "swapExactTokensForTokensAndSupplyAtSupportingFee", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "newOwner", + "name": "to", "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "vBnb", + "name": "swapExactTokensForTokensAtSupportingFee", "outputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "vai", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "_logic", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" }, { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - } - ] - }, - "ChainlinkOracle_Implementation": { - "address": "0xa074529FD3d0E7261A730d0f867107BA0C20d74A", - "abi": [ - { - "inputs": [ + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "address", - "name": "vBnbAddress", + "name": "to", "type": "address" }, { - "internalType": "address", - "name": "vaiAddress", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactBNB", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "stateMutability": "nonpayable", - "type": "constructor" + "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "sender", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "internalType": "address", - "name": "calledContract", - "type": "address" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" }, { - "internalType": "string", - "name": "methodSignature", - "type": "string" - } - ], - "name": "Unauthorized", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "oldAccessControlManager", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": false, - "internalType": "address", - "name": "newAccessControlManager", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "NewAccessControlManager", - "type": "event" + "name": "swapTokensForExactBNBAndRepay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferStarted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "OwnershipTransferred", - "type": "event" + "name": "swapTokensForExactBNBAndSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, "internalType": "uint256", - "name": "previousPriceMantissa", + "name": "amountOut", "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "newPriceMantissa", + "name": "amountInMax", "type": "uint256" - } - ], - "name": "PricePosted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" + "internalType": "address[]", + "name": "path", + "type": "address[]" }, { - "indexed": false, "internalType": "address", - "name": "feed", + "name": "to", "type": "address" }, { - "indexed": false, "internalType": "uint256", - "name": "maxStalePeriod", + "name": "deadline", "type": "uint256" } ], - "name": "TokenConfigAdded", - "type": "event" - }, - { - "inputs": [], - "name": "BNB_ADDR", + "name": "swapTokensForExactTokens", "outputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [], - "name": "accessControlManager", - "outputs": [ - { - "internalType": "contract IAccessControlManagerV8", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "vTokenAddress", "type": "address" - } - ], - "name": "getUnderlyingPrice", - "outputs": [ + }, { "internalType": "uint256", - "name": "", + "name": "amountOut", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "accessControlManager_", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + }, { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "prices", - "outputs": [ + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, { "internalType": "uint256", - "name": "", + "name": "deadline", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", + "name": "swapTokensForExactTokensAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -44378,59 +43941,31 @@ "inputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "vTokenAddress", "type": "address" - } - ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, { - "internalType": "address", - "name": "asset", - "type": "address" + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" }, { "internalType": "uint256", - "name": "price", + "name": "amountInMax", "type": "uint256" - } - ], - "name": "setDirectPrice", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address", - "name": "feed", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxStalePeriod", - "type": "uint256" - } - ], - "internalType": "struct ChainlinkOracle.TokenConfig", - "name": "tokenConfig", - "type": "tuple" + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "setTokenConfig", + "name": "swapTokensForExactTokensAndSupply", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -44438,29 +43973,22 @@ { "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address", - "name": "feed", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxStalePeriod", - "type": "uint256" - } - ], - "internalType": "struct ChainlinkOracle.TokenConfig[]", - "name": "tokenConfigs_", - "type": "tuple[]" + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" } ], - "name": "setTokenConfigs", + "name": "swapTokensForFullBNBDebtAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -44468,17 +43996,27 @@ { "inputs": [ { - "internalType": "contract VBep20Interface", - "name": "vToken", + "internalType": "address", + "name": "vTokenAddress", "type": "address" }, { "internalType": "uint256", - "name": "underlyingPriceMantissa", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "deadline", "type": "uint256" } ], - "name": "setUnderlyingPrice", + "name": "swapTokensForFullTokenDebtAndRepay", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -44486,30 +44024,24 @@ { "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "tokenConfigs", - "outputs": [ - { - "internalType": "address", - "name": "asset", + "internalType": "contract IERC20", + "name": "token", "type": "address" }, { "internalType": "address", - "name": "feed", + "name": "to", "type": "address" }, { "internalType": "uint256", - "name": "maxStalePeriod", + "name": "sweepAmount", "type": "uint256" } ], - "stateMutability": "view", + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { @@ -44527,7 +44059,7 @@ }, { "inputs": [], - "name": "vBnb", + "name": "vBNBAddress", "outputs": [ { "internalType": "address", @@ -44539,74 +44071,42 @@ "type": "function" }, { - "inputs": [], - "name": "vai", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "receive" } ] }, - "ChainlinkOracle_Proxy": { - "address": "0xCeA29f1266e880A1482c06eD656cD08C148BaA32", + "VTokenBeacon": { + "address": "0xBF85A90673E61956f8c79b9150BAB7893b791bDd", "abi": [ { "inputs": [ { "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", + "name": "implementation_", "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "previousAdmin", + "name": "previousOwner", "type": "address" }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ { "indexed": true, "internalType": "address", - "name": "beacon", + "name": "newOwner", "type": "address" } ], - "name": "BeaconUpgraded", + "name": "OwnershipTransferred", "type": "event" }, { @@ -44622,45 +44122,48 @@ "name": "Upgraded", "type": "event" }, - { - "stateMutability": "payable", - "type": "fallback" - }, { "inputs": [], - "name": "admin", + "name": "implementation", "outputs": [ { "internalType": "address", - "name": "admin_", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "implementation", + "name": "owner", "outputs": [ { "internalType": "address", - "name": "implementation_", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "newOwner", "type": "address" } ], - "name": "upgradeTo", + "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -44671,209 +44174,210 @@ "internalType": "address", "name": "newImplementation", "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" } ], - "name": "upgradeToAndCall", + "name": "upgradeTo", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" } ] }, - "DefaultProxyAdmin": { - "address": "0xef480a5654b231ff7d80A0681F938f3Db71a6Ca6", + "VTokenImpl": { + "address": "0x91D2c7BCA6Ea3313E07e0F6B3D0D00c4Fae482df", "abi": [ { - "inputs": [ - { - "internalType": "address", - "name": "initialOwner", - "type": "address" - } - ], + "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "uint256", + "name": "actualAddAmount", + "type": "uint256" } ], - "name": "OwnershipTransferred", - "type": "event" + "name": "AddReservesFactorFreshCheck", + "type": "error" }, { - "inputs": [ - { - "internalType": "contract TransparentUpgradeableProxy", - "name": "proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "changeProxyAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "inputs": [], + "name": "BorrowCashNotAvailable", + "type": "error" }, { - "inputs": [ - { - "internalType": "contract TransparentUpgradeableProxy", - "name": "proxy", - "type": "address" - } - ], - "name": "getProxyAdmin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "inputs": [], + "name": "BorrowFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "ForceLiquidateBorrowUnauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "HealBorrowUnauthorized", + "type": "error" }, { "inputs": [ { - "internalType": "contract TransparentUpgradeableProxy", - "name": "proxy", - "type": "address" - } - ], - "name": "getProxyImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "LiquidateAccrueCollateralInterestFailed", + "type": "error" }, { "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "name": "LiquidateCloseAmountIsUintMax", + "type": "error" }, { "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "LiquidateCloseAmountIsZero", + "type": "error" }, { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "inputs": [], + "name": "LiquidateCollateralFreshnessCheck", + "type": "error" }, { - "inputs": [ - { - "internalType": "contract TransparentUpgradeableProxy", - "name": "proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "upgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "inputs": [], + "name": "LiquidateFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidateLiquidatorIsBorrower", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidateSeizeLiquidatorIsBorrower", + "type": "error" + }, + { + "inputs": [], + "name": "MintFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "ProtocolSeizeShareTooBig", + "type": "error" + }, + { + "inputs": [], + "name": "RedeemFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "RedeemTransferOutNotPossible", + "type": "error" + }, + { + "inputs": [], + "name": "ReduceReservesCashNotAvailable", + "type": "error" + }, + { + "inputs": [], + "name": "ReduceReservesCashValidation", + "type": "error" + }, + { + "inputs": [], + "name": "ReduceReservesFreshCheck", + "type": "error" + }, + { + "inputs": [], + "name": "RepayBorrowFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetInterestRateModelFreshCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetReserveFactorBoundsCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetReserveFactorFreshCheck", + "type": "error" + }, + { + "inputs": [], + "name": "TransferNotAllowed", + "type": "error" }, { "inputs": [ { - "internalType": "contract TransparentUpgradeableProxy", - "name": "proxy", + "internalType": "address", + "name": "sender", "type": "address" }, { "internalType": "address", - "name": "implementation", + "name": "calledContract", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "string", + "name": "methodSignature", + "type": "string" } ], - "name": "upgradeAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } - ] - }, - "PythOracle": { - "address": "0x94E1534c14e0736BB24decA625f2F5364B198E0C", - "abi": [ + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, { "anonymous": false, "inputs": [ { "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "cashPrior", + "type": "uint256" }, { "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" } ], - "name": "AdminChanged", + "name": "AccrueInterest", "type": "event" }, { @@ -44882,111 +44386,130 @@ { "indexed": true, "internalType": "address", - "name": "beacon", + "name": "owner", "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { "indexed": true, "internalType": "address", - "name": "implementation", + "name": "spender", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "Upgraded", + "name": "Approval", "type": "event" }, { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "admin_", + "name": "borrower", "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ + }, { - "internalType": "address", - "name": "implementation_", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "badDebtDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtOld", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtNew", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "BadDebtIncreased", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "address", - "name": "newImplementation", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "badDebtOld", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtNew", + "type": "uint256" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "BadDebtRecovered", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newImplementation", + "name": "borrower", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" } ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" + "name": "Borrow", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "sender", + "name": "payer", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "calledContract", + "name": "borrower", "type": "address" }, { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" } ], - "name": "Unauthorized", - "type": "error" + "name": "HealBorrow", + "type": "event" }, { "anonymous": false, @@ -45005,19 +44528,37 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "oldAccessControlManager", + "name": "liquidator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", "type": "address" }, { "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": true, "internalType": "address", - "name": "newAccessControlManager", + "name": "vTokenCollateral", "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" } ], - "name": "NewAccessControlManager", + "name": "LiquidateBorrow", "type": "event" }, { @@ -45026,36 +44567,48 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "minter", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBalance", + "type": "uint256" } ], - "name": "OwnershipTransferStarted", + "name": "Mint", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "previousOwner", + "name": "oldAccessControlManager", "type": "address" }, { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "newOwner", + "name": "newAccessControlManager", "type": "address" } ], - "name": "OwnershipTransferred", + "name": "NewAccessControlManager", "type": "event" }, { @@ -45063,18 +44616,18 @@ "inputs": [ { "indexed": true, - "internalType": "address", - "name": "oldPythOracle", + "internalType": "contract ComptrollerInterface", + "name": "oldComptroller", "type": "address" }, { "indexed": true, - "internalType": "address", - "name": "newPythOracle", + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", "type": "address" } ], - "name": "PythOracleSet", + "name": "NewComptroller", "type": "event" }, { @@ -45082,402 +44635,200 @@ "inputs": [ { "indexed": true, - "internalType": "address", - "name": "vToken", + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", "type": "address" }, { "indexed": true, - "internalType": "bytes32", - "name": "pythId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "maxStalePeriod", - "type": "uint64" - } - ], - "name": "TokenConfigAdded", - "type": "event" - }, - { - "inputs": [], - "name": "BNB_ADDR", - "outputs": [ - { - "internalType": "address", - "name": "", + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "NewMarketInterestRateModel", + "type": "event" }, { - "inputs": [], - "name": "EXP_SCALE", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "oldProtocolSeizeShareMantissa", "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "accessControlManager", - "outputs": [ - { - "internalType": "contract IAccessControlManagerV8", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "vToken", - "type": "address" - } - ], - "name": "getUnderlyingPrice", - "outputs": [ + }, { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "newProtocolSeizeShareMantissa", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "NewProtocolSeizeShare", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "underlyingPythOracle_", + "name": "oldProtocolShareReserve", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "accessControlManager_", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "accessControlManager_", + "name": "newProtocolShareReserve", "type": "address" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "pythId", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint64", - "name": "maxStalePeriod", - "type": "uint64" - } - ], - "internalType": "struct PythOracle.TokenConfig", - "name": "tokenConfig", - "type": "tuple" - } - ], - "name": "setTokenConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "NewProtocolShareReserve", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "components": [ - { - "internalType": "bytes32", - "name": "pythId", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint64", - "name": "maxStalePeriod", - "type": "uint64" - } - ], - "internalType": "struct PythOracle.TokenConfig[]", - "name": "tokenConfigs_", - "type": "tuple[]" - } - ], - "name": "setTokenConfigs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "indexed": false, + "internalType": "uint256", + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, { - "internalType": "contract IPyth", - "name": "underlyingPythOracle_", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" } ], - "name": "setUnderlyingPythOracle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "NewReserveFactor", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "oldShortfall", "type": "address" - } - ], - "name": "tokenConfigs", - "outputs": [ - { - "internalType": "bytes32", - "name": "pythId", - "type": "bytes32" }, { + "indexed": true, "internalType": "address", - "name": "asset", + "name": "newShortfall", "type": "address" - }, - { - "internalType": "uint64", - "name": "maxStalePeriod", - "type": "uint64" } ], - "stateMutability": "view", - "type": "function" + "name": "NewShortfallContract", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "previousOwner", "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "underlyingPythOracle", - "outputs": [ + }, { - "internalType": "contract IPyth", - "name": "", + "indexed": true, + "internalType": "address", + "name": "newOwner", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "OwnershipTransferStarted", + "type": "event" }, { - "inputs": [], - "name": "vBnb", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "previousOwner", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "vai", - "outputs": [ + }, { + "indexed": true, "internalType": "address", - "name": "", + "name": "newOwner", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "OwnershipTransferred", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "_logic", + "name": "redeemer", "type": "address" }, { - "internalType": "address", - "name": "admin_", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" }, { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - } - ] - }, - "PythOracle_Implementation": { - "address": "0xb8a450101DF8ab770c8F8521E189a4B39e7Cf5f5", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "vBnbAddress", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" }, { - "internalType": "address", - "name": "vaiAddress", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "accountBalance", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "constructor" + "name": "Redeem", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "sender", + "name": "payer", "type": "address" }, { + "indexed": true, "internalType": "address", - "name": "calledContract", + "name": "borrower", "type": "address" }, - { - "internalType": "string", - "name": "methodSignature", - "type": "string" - } - ], - "name": "Unauthorized", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ { "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, { "indexed": false, - "internalType": "address", - "name": "oldAccessControlManager", - "type": "address" + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" }, { "indexed": false, - "internalType": "address", - "name": "newAccessControlManager", - "type": "address" + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" } ], - "name": "NewAccessControlManager", + "name": "RepayBorrow", "type": "event" }, { @@ -45486,17 +44837,23 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "benefactor", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" } ], - "name": "OwnershipTransferStarted", + "name": "ReservesAdded", "type": "event" }, { @@ -45505,17 +44862,23 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "admin", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "indexed": false, + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" } ], - "name": "OwnershipTransferred", + "name": "ReservesReduced", "type": "event" }, { @@ -45524,17 +44887,11 @@ { "indexed": true, "internalType": "address", - "name": "oldPythOracle", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newPythOracle", + "name": "token", "type": "address" } ], - "name": "PythOracleSet", + "name": "SweepToken", "type": "event" }, { @@ -45543,41 +44900,28 @@ { "indexed": true, "internalType": "address", - "name": "vToken", + "name": "from", "type": "address" }, { "indexed": true, - "internalType": "bytes32", - "name": "pythId", - "type": "bytes32" + "internalType": "address", + "name": "to", + "type": "address" }, { - "indexed": true, - "internalType": "uint64", - "name": "maxStalePeriod", - "type": "uint64" + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "TokenConfigAdded", + "name": "Transfer", "type": "event" }, { "inputs": [], - "name": "BNB_ADDR", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "EXP_SCALE", + "name": "NO_ERROR", "outputs": [ { "internalType": "uint256", @@ -45609,14 +44953,21 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ { - "internalType": "address", - "name": "vToken", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "getUnderlyingPrice", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accrueInterest", "outputs": [ { "internalType": "uint256", @@ -45624,142 +44975,92 @@ "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "underlyingPythOracle_", - "type": "address" - }, - { - "internalType": "address", - "name": "accessControlManager_", - "type": "address" + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" } ], - "name": "initialize", + "name": "addReserves", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", "type": "address" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", + "name": "allowance", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "spender", "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + "name": "approve", + "outputs": [ { - "components": [ - { - "internalType": "bytes32", - "name": "pythId", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint64", - "name": "maxStalePeriod", - "type": "uint64" - } - ], - "internalType": "struct PythOracle.TokenConfig", - "name": "tokenConfig", - "type": "tuple" + "internalType": "bool", + "name": "", + "type": "bool" } ], - "name": "setTokenConfig", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "badDebt", + "outputs": [ { - "components": [ - { - "internalType": "bytes32", - "name": "pythId", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint64", - "name": "maxStalePeriod", - "type": "uint64" - } - ], - "internalType": "struct PythOracle.TokenConfig[]", - "name": "tokenConfigs_", - "type": "tuple[]" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "setTokenConfigs", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { - "internalType": "contract IPyth", - "name": "underlyingPythOracle_", - "type": "address" + "internalType": "uint256", + "name": "recoveredAmount_", + "type": "uint256" } ], - "name": "setUnderlyingPythOracle", + "name": "badDebtRecovered", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -45768,26 +45069,16 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "owner", "type": "address" } ], - "name": "tokenConfigs", + "name": "balanceOf", "outputs": [ { - "internalType": "bytes32", - "name": "pythId", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint64", - "name": "maxStalePeriod", - "type": "uint64" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], "stateMutability": "view", @@ -45797,252 +45088,162 @@ "inputs": [ { "internalType": "address", - "name": "newOwner", + "name": "owner", "type": "address" } ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "underlyingPythOracle", + "name": "balanceOfUnderlying", "outputs": [ { - "internalType": "contract IPyth", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "vBnb", - "outputs": [ + "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "vai", + "name": "borrow", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" - } - ] - }, - "PythOracle_Proxy": { - "address": "0x94E1534c14e0736BB24decA625f2F5364B198E0C", - "abi": [ + }, { "inputs": [ { "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", + "name": "account", "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" } ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, + "name": "borrowBalanceCurrent", + "outputs": [ { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "account", "type": "address" } ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "borrowBalanceStored", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "admin", + "name": "borrowIndex", "outputs": [ { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "implementation", + "name": "borrowRatePerBlock", "outputs": [ { - "internalType": "address", - "name": "implementation_", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "comptroller", + "outputs": [ { - "internalType": "address", - "name": "newImplementation", + "internalType": "contract ComptrollerInterface", + "name": "", "type": "address" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, + "inputs": [], + "name": "decimals", + "outputs": [ { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint8", + "name": "", + "type": "uint8" } ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "ResilientOracle": { - "address": "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823", - "abi": [ - { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "previousAdmin", + "name": "spender", "type": "address" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + "name": "decreaseAllowance", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "bool", + "name": "", + "type": "bool" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "admin", + "name": "exchangeRateCurrent", "outputs": [ { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], "stateMutability": "nonpayable", @@ -46050,266 +45251,307 @@ }, { "inputs": [], - "name": "implementation", + "name": "exchangeRateStored", "outputs": [ { - "internalType": "address", - "name": "implementation_", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "liquidator", "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ + }, { "internalType": "address", - "name": "newImplementation", + "name": "borrower", "type": "address" }, { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "internalType": "contract VTokenInterface", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "bool", + "name": "skipLiquidityCheck", + "type": "bool" } ], - "name": "upgradeToAndCall", + "name": "forceLiquidateBorrow", "outputs": [], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - }, { "inputs": [ { "internalType": "address", - "name": "sender", + "name": "account", "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "internalType": "uint256", + "name": "error", + "type": "uint256" }, { - "internalType": "address", - "name": "calledContract", - "type": "address" + "internalType": "uint256", + "name": "vTokenBalance", + "type": "uint256" }, { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "internalType": "uint256", + "name": "borrowBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" } ], - "name": "Unauthorized", - "type": "error" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "getCash", + "outputs": [ { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "Initialized", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, "internalType": "address", - "name": "oldAccessControlManager", + "name": "payer", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAccessControlManager", + "name": "borrower", "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" } ], - "name": "NewAccessControlManager", - "type": "event" + "name": "healBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "asset", + "name": "spender", "type": "address" }, { - "indexed": true, "internalType": "uint256", - "name": "role", + "name": "addedValue", "type": "uint256" - }, + } + ], + "name": "increaseAllowance", + "outputs": [ { - "indexed": true, "internalType": "bool", - "name": "enable", + "name": "", "type": "bool" } ], - "name": "OracleEnabled", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "asset", + "name": "underlying_", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "oracle", + "internalType": "contract ComptrollerInterface", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", "type": "address" }, { - "indexed": true, "internalType": "uint256", - "name": "role", + "name": "initialExchangeRateMantissa_", "type": "uint256" - } - ], - "name": "OracleSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "admin_", "type": "address" }, { - "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "accessControlManager_", "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "shortfall", + "type": "address" + }, + { + "internalType": "address payable", + "name": "protocolShareReserve", + "type": "address" + } + ], + "internalType": "struct VTokenInterface.RiskManagementInit", + "name": "riskManagement", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa_", + "type": "uint256" } ], - "name": "OwnershipTransferStarted", - "type": "event" + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, + "inputs": [], + "name": "interestRateModel", + "outputs": [ { - "indexed": true, - "internalType": "address", - "name": "newOwner", + "internalType": "contract InterestRateModel", + "name": "", "type": "address" } ], - "name": "OwnershipTransferred", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "isVToken", + "outputs": [ { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" + "internalType": "bool", + "name": "", + "type": "bool" } ], - "name": "Paused", - "type": "event" + "stateMutability": "pure", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "asset", + "name": "borrower", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "mainOracle", - "type": "address" + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" }, { - "indexed": true, - "internalType": "address", - "name": "pivotOracle", + "internalType": "contract VTokenInterface", + "name": "vTokenCollateral", "type": "address" - }, + } + ], + "name": "liquidateBorrow", + "outputs": [ { - "indexed": false, - "internalType": "address", - "name": "fallbackOracle", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "TokenConfigAdded", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" } ], - "name": "Unpaused", - "type": "event" - }, - { - "inputs": [], - "name": "BNB_ADDR", + "name": "mint", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "INVALID_PRICE", + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintBehalf", "outputs": [ { "internalType": "uint256", @@ -46317,24 +45559,17 @@ "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "accessControlManager", + "name": "name", "outputs": [ { - "internalType": "contract IAccessControlManagerV8", + "internalType": "string", "name": "", - "type": "address" + "type": "string" } ], "stateMutability": "view", @@ -46342,10 +45577,10 @@ }, { "inputs": [], - "name": "boundValidator", + "name": "owner", "outputs": [ { - "internalType": "contract BoundValidatorInterface", + "internalType": "address", "name": "", "type": "address" } @@ -46354,52 +45589,39 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "pendingOwner", + "outputs": [ { "internalType": "address", - "name": "asset", + "name": "", "type": "address" - }, - { - "internalType": "enum ResilientOracle.OracleRole", - "name": "role", - "type": "uint8" - }, - { - "internalType": "bool", - "name": "enable", - "type": "bool" } ], - "name": "enableOracle", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "vToken", - "type": "address" - }, + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [ { - "internalType": "enum ResilientOracle.OracleRole", - "name": "role", - "type": "uint8" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "getOracle", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolShareReserve", "outputs": [ { - "internalType": "address", - "name": "oracle", + "internalType": "address payable", + "name": "", "type": "address" - }, - { - "internalType": "bool", - "name": "enabled", - "type": "bool" } ], "stateMutability": "view", @@ -46408,48 +45630,31 @@ { "inputs": [ { - "internalType": "address", - "name": "vToken", - "type": "address" + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" } ], - "name": "getTokenConfig", + "name": "redeem", "outputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address[3]", - "name": "oracles", - "type": "address[3]" - }, - { - "internalType": "bool[3]", - "name": "enableFlagsForOracles", - "type": "bool[3]" - } - ], - "internalType": "struct ResilientOracle.TokenConfig", + "internalType": "uint256", "name": "", - "type": "tuple" + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "vToken", - "type": "address" + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" } ], - "name": "getUnderlyingPrice", + "name": "redeemUnderlying", "outputs": [ { "internalType": "uint256", @@ -46457,84 +45662,104 @@ "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", - "name": "accessControlManager_", - "type": "address" + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" } ], - "name": "initialize", + "name": "reduceReserves", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "owner", + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "paused", + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", "outputs": [ { - "internalType": "bool", + "internalType": "uint256", "name": "", - "type": "bool" + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "pendingOwner", + "name": "reserveFactorMantissa", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" } ], - "name": "setAccessControlManager", + "name": "seize", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -46543,21 +45768,11 @@ "inputs": [ { "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address", - "name": "oracle", + "name": "accessControlManager_", "type": "address" - }, - { - "internalType": "enum ResilientOracle.OracleRole", - "name": "role", - "type": "uint8" } ], - "name": "setOracle", + "name": "setAccessControlManager", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -46565,29 +45780,12 @@ { "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address[3]", - "name": "oracles", - "type": "address[3]" - }, - { - "internalType": "bool[3]", - "name": "enableFlagsForOracles", - "type": "bool[3]" - } - ], - "internalType": "struct ResilientOracle.TokenConfig", - "name": "tokenConfig", - "type": "tuple" + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" } ], - "name": "setTokenConfig", + "name": "setInterestRateModel", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -46595,29 +45793,12 @@ { "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address[3]", - "name": "oracles", - "type": "address[3]" - }, - { - "internalType": "bool[3]", - "name": "enableFlagsForOracles", - "type": "bool[3]" - } - ], - "internalType": "struct ResilientOracle.TokenConfig[]", - "name": "tokenConfigs_", - "type": "tuple[]" + "internalType": "uint256", + "name": "newProtocolSeizeShareMantissa_", + "type": "uint256" } ], - "name": "setTokenConfigs", + "name": "setProtocolSeizeShare", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -46625,19 +45806,25 @@ { "inputs": [ { - "internalType": "address", - "name": "newOwner", + "internalType": "address payable", + "name": "protocolShareReserve_", "type": "address" } ], - "name": "transferOwnership", + "name": "setProtocolShareReserve", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "unpause", + "inputs": [ + { + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "setReserveFactor", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -46646,18 +45833,18 @@ "inputs": [ { "internalType": "address", - "name": "vToken", + "name": "shortfall_", "type": "address" } ], - "name": "updatePrice", + "name": "setShortfallContract", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "vBnb", + "name": "shortfall", "outputs": [ { "internalType": "address", @@ -46670,12 +45857,12 @@ }, { "inputs": [], - "name": "vai", + "name": "supplyRatePerBlock", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", @@ -46684,202 +45871,211 @@ { "inputs": [ { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", + "internalType": "contract IERC20Upgradeable", + "name": "token", "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" } ], - "stateMutability": "payable", - "type": "constructor" - } - ] - }, - "ResilientOracle_Implementation": { - "address": "0xF53cFE89b4c3eFCbdd9aF712e94017454d43c181", - "abi": [ + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { - "inputs": [ - { - "internalType": "address", - "name": "vBnbAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "vaiAddress", - "type": "address" - }, + "inputs": [], + "name": "symbol", + "outputs": [ { - "internalType": "contract BoundValidatorInterface", - "name": "_boundValidator", - "type": "address" + "internalType": "string", + "name": "", + "type": "string" } ], - "stateMutability": "nonpayable", - "type": "constructor" + "stateMutability": "view", + "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "calledContract", - "type": "address" - }, + "inputs": [], + "name": "totalBorrows", + "outputs": [ { - "internalType": "string", - "name": "methodSignature", - "type": "string" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "Unauthorized", - "type": "error" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "Initialized", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "totalReserves", + "outputs": [ { - "indexed": false, - "internalType": "address", - "name": "oldAccessControlManager", - "type": "address" - }, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ { - "indexed": false, - "internalType": "address", - "name": "newAccessControlManager", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "NewAccessControlManager", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "asset", + "name": "dst", "type": "address" }, { - "indexed": true, "internalType": "uint256", - "name": "role", + "name": "amount", "type": "uint256" - }, + } + ], + "name": "transfer", + "outputs": [ { - "indexed": true, "internalType": "bool", - "name": "enable", + "name": "", "type": "bool" } ], - "name": "OracleEnabled", - "type": "event" + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "asset", + "name": "src", "type": "address" }, { - "indexed": true, "internalType": "address", - "name": "oracle", + "name": "dst", "type": "address" }, { - "indexed": true, "internalType": "uint256", - "name": "role", + "name": "amount", "type": "uint256" } ], - "name": "OracleSet", - "type": "event" + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "newOwner", "type": "address" - }, + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "", "type": "address" } ], - "name": "OwnershipTransferStarted", - "type": "event" + "stateMutability": "view", + "type": "function" + } + ] + }, + "VToken_vALPACA_DeFi": { + "address": "0xb7caC5Ef82cb7f9197ee184779bdc52c5490C02a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "beacon", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" }, { "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "previousOwner", + "name": "previousAdmin", "type": "address" }, { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "newOwner", + "name": "newAdmin", "type": "address" } ], - "name": "OwnershipTransferred", + "name": "AdminChanged", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "account", + "name": "beacon", "type": "address" } ], - "name": "Paused", + "name": "BeaconUpgraded", "type": "event" }, { @@ -46888,451 +46084,480 @@ { "indexed": true, "internalType": "address", - "name": "asset", + "name": "implementation", "type": "address" - }, + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vANKR_DeFi": { + "address": "0xb677e080148368EeeE70fA3865d07E92c6500174", + "abi": [ + { + "inputs": [ { - "indexed": true, "internalType": "address", - "name": "mainOracle", + "name": "beacon", "type": "address" }, { - "indexed": true, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, "internalType": "address", - "name": "pivotOracle", + "name": "previousAdmin", "type": "address" }, { "indexed": false, "internalType": "address", - "name": "fallbackOracle", + "name": "newAdmin", "type": "address" } ], - "name": "TokenConfigAdded", + "name": "AdminChanged", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", - "name": "account", + "name": "beacon", "type": "address" } ], - "name": "Unpaused", + "name": "BeaconUpgraded", "type": "event" }, { - "inputs": [], - "name": "BNB_ADDR", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "implementation", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "Upgraded", + "type": "event" }, { - "inputs": [], - "name": "INVALID_PRICE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "fallback" }, { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vBNBx_LiquidStakedBNB": { + "address": "0x644A149853E5507AdF3e682218b8AC86cdD62951", + "abi": [ { - "inputs": [], - "name": "accessControlManager", - "outputs": [ + "inputs": [ { - "internalType": "contract IAccessControlManagerV8", - "name": "", + "internalType": "address", + "name": "beacon", "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { - "inputs": [], - "name": "boundValidator", - "outputs": [ + "anonymous": false, + "inputs": [ { - "internalType": "contract BoundValidatorInterface", - "name": "", + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "asset", + "name": "beacon", "type": "address" - }, - { - "internalType": "enum ResilientOracle.OracleRole", - "name": "role", - "type": "uint8" - }, - { - "internalType": "bool", - "name": "enable", - "type": "bool" } ], - "name": "enableOracle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vToken", + "name": "implementation", "type": "address" - }, - { - "internalType": "enum ResilientOracle.OracleRole", - "name": "role", - "type": "uint8" } ], - "name": "getOracle", - "outputs": [ + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vBSW_DeFi": { + "address": "0x5e68913fbbfb91af30366ab1B21324410b49a308", + "abi": [ + { + "inputs": [ { "internalType": "address", - "name": "oracle", + "name": "beacon", "type": "address" }, { - "internalType": "bool", - "name": "enabled", - "type": "bool" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "vToken", + "name": "previousAdmin", "type": "address" - } - ], - "name": "getTokenConfig", - "outputs": [ + }, { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address[3]", - "name": "oracles", - "type": "address[3]" - }, - { - "internalType": "bool[3]", - "name": "enableFlagsForOracles", - "type": "bool[3]" - } - ], - "internalType": "struct ResilientOracle.TokenConfig", - "name": "", - "type": "tuple" + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vToken", + "name": "beacon", "type": "address" } ], - "name": "getUnderlyingPrice", - "outputs": [ + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vBTT_Tron": { + "address": "0x47793540757c6E6D84155B33cd8D9535CFdb9334", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "beacon", "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address", - "name": "", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", "type": "address" } ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { - "inputs": [], - "name": "paused", - "outputs": [ + "anonymous": false, + "inputs": [ { - "internalType": "bool", - "name": "", - "type": "bool" + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "implementation", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "Upgraded", + "type": "event" }, { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "payable", + "type": "fallback" }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vFLOKI_GameFi": { + "address": "0xef470AbC365F88e4582D8027172a392C473A5B53", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "accessControlManager_", + "name": "beacon", "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "asset", + "name": "previousAdmin", "type": "address" }, { + "indexed": false, "internalType": "address", - "name": "oracle", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "enum ResilientOracle.OracleRole", - "name": "role", - "type": "uint8" } ], - "name": "setOracle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address[3]", - "name": "oracles", - "type": "address[3]" - }, - { - "internalType": "bool[3]", - "name": "enableFlagsForOracles", - "type": "bool[3]" - } - ], - "internalType": "struct ResilientOracle.TokenConfig", - "name": "tokenConfig", - "type": "tuple" + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" } ], - "name": "setTokenConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "address[3]", - "name": "oracles", - "type": "address[3]" - }, - { - "internalType": "bool[3]", - "name": "enableFlagsForOracles", - "type": "bool[3]" - } - ], - "internalType": "struct ResilientOracle.TokenConfig[]", - "name": "tokenConfigs_", - "type": "tuple[]" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "name": "setTokenConfigs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vHAY_StableCoins": { + "address": "0x170d3b2da05cc2124334240fB34ad1359e34C562", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "newOwner", + "name": "beacon", "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { + "anonymous": false, "inputs": [ { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, "internalType": "address", - "name": "vToken", + "name": "newAdmin", "type": "address" } ], - "name": "updatePrice", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { - "inputs": [], - "name": "vBnb", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "beacon", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { - "inputs": [], - "name": "vai", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "implementation", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" } ] }, - "ResilientOracle_Proxy": { - "address": "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823", + "VToken_vNFT_Tron": { + "address": "0x67cD2A8aFF63C7eBbC7A601506f9Dbb8557d6547", "abi": [ { "inputs": [ { "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", + "name": "beacon", "type": "address" }, { "internalType": "bytes", - "name": "_data", + "name": "data", "type": "bytes" } ], @@ -47389,61 +46614,78 @@ "type": "fallback" }, { - "inputs": [], - "name": "admin", - "outputs": [ + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vRACA_GameFi": { + "address": "0x1958035231E125830bA5d17D168cEa07Bb42184a", + "abi": [ + { + "inputs": [ { "internalType": "address", - "name": "admin_", + "name": "beacon", "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { - "inputs": [], - "name": "implementation", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address", - "name": "implementation_", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", "type": "address" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newImplementation", + "name": "beacon", "type": "address" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newImplementation", + "name": "implementation", "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" } ], - "name": "upgradeToAndCall", - "outputs": [], + "name": "Upgraded", + "type": "event" + }, + { "stateMutability": "payable", - "type": "function" + "type": "fallback" }, { "stateMutability": "payable", @@ -47451,9 +46693,25 @@ } ] }, - "TwapOracle": { - "address": "0x3eeE05d929D1E9816185B1b6d8c470eC192b4432", + "VToken_vTRX_Tron": { + "address": "0x410286c43a525E1DCC7468a9B091C111C8324cd1", "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "beacon", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, { "anonymous": false, "inputs": [ @@ -47504,49 +46762,93 @@ "type": "fallback" }, { - "inputs": [], - "name": "admin", - "outputs": [ + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDD_DeFi": { + "address": "0xa109DE0abaeefC521Ec29D89eA42E64F37A6882E", + "abi": [ + { + "inputs": [ { "internalType": "address", - "name": "admin_", + "name": "beacon", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", "type": "address" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { - "inputs": [], - "name": "implementation", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "implementation_", + "name": "beacon", "type": "address" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newImplementation", + "name": "implementation", "type": "address" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDD_GameFi": { + "address": "0xdeDf3B2bcF25d0023115fd71a0F8221C91C92B1a", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "beacon", "type": "address" }, { @@ -47555,35 +46857,27 @@ "type": "bytes" } ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { "stateMutability": "payable", - "type": "receive" + "type": "constructor" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "sender", + "name": "previousAdmin", "type": "address" }, { + "indexed": false, "internalType": "address", - "name": "calledContract", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "string", - "name": "methodSignature", - "type": "string" } ], - "name": "Unauthorized", - "type": "error" + "name": "AdminChanged", + "type": "event" }, { "anonymous": false, @@ -47591,61 +46885,72 @@ { "indexed": true, "internalType": "address", - "name": "asset", + "name": "beacon", "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "price", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "oldTimestamp", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newTimestamp", - "type": "uint256" } ], - "name": "AnchorPriceUpdated", + "name": "BeaconUpgraded", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "name": "Initialized", + "name": "Upgraded", "type": "event" }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDD_LiquidStakedBNB": { + "address": "0xD5b20708d8f0FcA52cb609938D0594C4e32E5DaD", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "beacon", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "address", - "name": "oldAccessControlManager", + "name": "previousAdmin", "type": "address" }, { "indexed": false, "internalType": "address", - "name": "newAccessControlManager", + "name": "newAdmin", "type": "address" } ], - "name": "NewAccessControlManager", + "name": "AdminChanged", "type": "event" }, { @@ -47654,61 +46959,72 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "implementation", "type": "address" } ], - "name": "OwnershipTransferStarted", + "name": "Upgraded", "type": "event" }, { - "anonymous": false, + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDD_StableCoins": { + "address": "0x899dDf81DfbbF5889a16D075c352F2b959Dd24A4", + "abi": [ + { "inputs": [ { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "beacon", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "OwnershipTransferred", - "type": "event" + "stateMutability": "payable", + "type": "constructor" }, { "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "asset", + "name": "previousAdmin", "type": "address" }, { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "pancakePool", + "name": "newAdmin", "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" } ], - "name": "TokenConfigAdded", + "name": "AdminChanged", "type": "event" }, { @@ -47717,551 +47033,369 @@ { "indexed": true, "internalType": "address", - "name": "asset", + "name": "beacon", "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "oldTimestamp", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "oldAcc", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newTimestamp", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newAcc", - "type": "uint256" } ], - "name": "TwapWindowUpdated", + "name": "BeaconUpgraded", "type": "event" }, { - "inputs": [], - "name": "BNB_BASE_UNIT", - "outputs": [ + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "Upgraded", + "type": "event" }, { - "inputs": [], - "name": "BUSD_BASE_UNIT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "fallback" }, { - "inputs": [], - "name": "WBNB", - "outputs": [ + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDD_Tron": { + "address": "0xD804F74fe21290d213c46610ab171f7c2EeEBDE7", + "abi": [ + { + "inputs": [ { "internalType": "address", - "name": "", + "name": "beacon", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "accessControlManager", - "outputs": [ + }, { - "internalType": "contract IAccessControlManagerV8", - "name": "", - "type": "address" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { + "anonymous": false, "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "baseUnit", - "type": "uint256" - }, - { - "internalType": "address", - "name": "pancakePool", - "type": "address" - }, - { - "internalType": "bool", - "name": "isBnbBased", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isReversedPool", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" - } - ], - "internalType": "struct TwapOracle.TokenConfig", - "name": "config", - "type": "tuple" - } - ], - "name": "currentCumulativePrice", - "outputs": [ + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, { - "internalType": "uint256", - "name": "", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vToken", + "name": "beacon", "type": "address" } ], - "name": "getUnderlyingPrice", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "accessControlManager_", + "name": "implementation", "type": "address" } ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDT_DeFi": { + "address": "0x80CC30811e362aC9aB857C3d7875CbcCc0b65750", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "", + "name": "beacon", "type": "address" }, { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "observations", - "outputs": [ - { - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "acc", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address", - "name": "", + "name": "previousAdmin", "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + }, { + "indexed": false, "internalType": "address", - "name": "", + "name": "newAdmin", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "beacon", "type": "address" } ], - "name": "prices", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "accessControlManager_", + "name": "implementation", "type": "address" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "Upgraded", + "type": "event" }, { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "baseUnit", - "type": "uint256" - }, - { - "internalType": "address", - "name": "pancakePool", - "type": "address" - }, - { - "internalType": "bool", - "name": "isBnbBased", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isReversedPool", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" - } - ], - "internalType": "struct TwapOracle.TokenConfig", - "name": "config", - "type": "tuple" - } - ], - "name": "setTokenConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "payable", + "type": "fallback" }, { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "baseUnit", - "type": "uint256" - }, - { - "internalType": "address", - "name": "pancakePool", - "type": "address" - }, - { - "internalType": "bool", - "name": "isBnbBased", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isReversedPool", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" - } - ], - "internalType": "struct TwapOracle.TokenConfig[]", - "name": "configs", - "type": "tuple[]" - } - ], - "name": "setTokenConfigs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDT_GameFi": { + "address": "0x0bFE4e0B8A2a096A27e5B18b078d25be57C08634", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "", + "name": "beacon", "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "tokenConfigs", - "outputs": [ + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address", - "name": "asset", + "name": "previousAdmin", "type": "address" }, { - "internalType": "uint256", - "name": "baseUnit", - "type": "uint256" - }, - { + "indexed": false, "internalType": "address", - "name": "pancakePool", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "bool", - "name": "isBnbBased", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isReversedPool", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "beacon", "type": "address" } ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vToken", + "name": "implementation", "type": "address" } ], - "name": "updateTwap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" + "name": "Upgraded", + "type": "event" }, { - "inputs": [], - "name": "vBnb", - "outputs": [ + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDT_LiquidStakedBNB": { + "address": "0x2197d02cC9cd1ad51317A0a85A656a0c82383A7c", + "abi": [ + { + "inputs": [ { "internalType": "address", - "name": "", + "name": "beacon", "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { - "inputs": [], - "name": "vai", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address", - "name": "", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "beacon", "type": "address" } ], - "name": "windowStart", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", + "name": "implementation", "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" } ], + "name": "Upgraded", + "type": "event" + }, + { "stateMutability": "payable", - "type": "constructor" + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" } ] }, - "TwapOracle_Implementation": { - "address": "0x572ec272B4Ae3a50B99905AFd78671F84474ffd1", + "VToken_vUSDT_StableCoins": { + "address": "0x3338988d0beb4419Acb8fE624218754053362D06", "abi": [ { "inputs": [ { "internalType": "address", - "name": "vBnbAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "wBnbAddress", + "name": "beacon", "type": "address" }, { - "internalType": "address", - "name": "vaiAddress", - "type": "address" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "nonpayable", + "stateMutability": "payable", "type": "constructor" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "sender", + "name": "previousAdmin", "type": "address" }, { + "indexed": false, "internalType": "address", - "name": "calledContract", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "string", - "name": "methodSignature", - "type": "string" } ], - "name": "Unauthorized", - "type": "error" + "name": "AdminChanged", + "type": "event" }, { "anonymous": false, @@ -48269,61 +47403,72 @@ { "indexed": true, "internalType": "address", - "name": "asset", + "name": "beacon", "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "price", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "oldTimestamp", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newTimestamp", - "type": "uint256" } ], - "name": "AnchorPriceUpdated", + "name": "BeaconUpgraded", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "name": "Initialized", + "name": "Upgraded", "type": "event" }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vUSDT_Tron": { + "address": "0x712774CBFFCBD60e9825871CcEFF2F917442b2c3", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "beacon", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "address", - "name": "oldAccessControlManager", + "name": "previousAdmin", "type": "address" }, { "indexed": false, "internalType": "address", - "name": "newAccessControlManager", + "name": "newAdmin", "type": "address" } ], - "name": "NewAccessControlManager", + "name": "AdminChanged", "type": "event" }, { @@ -48332,61 +47477,85 @@ { "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, "internalType": "address", - "name": "newOwner", + "name": "implementation", "type": "address" } ], - "name": "OwnershipTransferStarted", + "name": "Upgraded", "type": "event" }, { - "anonymous": false, + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vWBNB_LiquidStakedBNB": { + "address": "0x231dED0Dfc99634e52EE1a1329586bc970d773b3", + "abi": [ + { "inputs": [ { - "indexed": true, "internalType": "address", - "name": "previousOwner", + "name": "beacon", "type": "address" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "OwnershipTransferred", - "type": "event" + "stateMutability": "payable", + "type": "constructor" }, { "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "asset", + "name": "previousAdmin", "type": "address" }, { - "indexed": true, + "indexed": false, "internalType": "address", - "name": "pancakePool", + "name": "newAdmin", "type": "address" - }, + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" + "internalType": "address", + "name": "beacon", + "type": "address" } ], - "name": "TokenConfigAdded", + "name": "BeaconUpgraded", "type": "event" }, { @@ -48395,360 +47564,394 @@ { "indexed": true, "internalType": "address", - "name": "asset", + "name": "implementation", "type": "address" - }, + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vWIN_Tron": { + "address": "0xEe543D5de2Dbb5b07675Fc72831A2f1812428393", + "abi": [ + { + "inputs": [ { - "indexed": false, - "internalType": "uint256", - "name": "oldTimestamp", - "type": "uint256" + "internalType": "address", + "name": "beacon", + "type": "address" }, { - "indexed": false, - "internalType": "uint256", - "name": "oldAcc", - "type": "uint256" - }, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ { "indexed": false, - "internalType": "uint256", - "name": "newTimestamp", - "type": "uint256" + "internalType": "address", + "name": "previousAdmin", + "type": "address" }, { "indexed": false, - "internalType": "uint256", - "name": "newAcc", - "type": "uint256" + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "name": "TwapWindowUpdated", + "name": "AdminChanged", "type": "event" }, { - "inputs": [], - "name": "BNB_BASE_UNIT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "BUSD_BASE_UNIT", - "outputs": [ + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { - "inputs": [], - "name": "WBNB", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "implementation", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "Upgraded", + "type": "event" }, { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "payable", + "type": "fallback" }, { - "inputs": [], - "name": "accessControlManager", - "outputs": [ + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vankrBNB_DeFi": { + "address": "0xe507B30C41E9e375BCe05197c1e09fc9ee40c0f6", + "abi": [ + { + "inputs": [ { - "internalType": "contract IAccessControlManagerV8", - "name": "", + "internalType": "address", + "name": "beacon", "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { + "anonymous": false, "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "baseUnit", - "type": "uint256" - }, - { - "internalType": "address", - "name": "pancakePool", - "type": "address" - }, - { - "internalType": "bool", - "name": "isBnbBased", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isReversedPool", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" - } - ], - "internalType": "struct TwapOracle.TokenConfig", - "name": "config", - "type": "tuple" - } - ], - "name": "currentCumulativePrice", - "outputs": [ + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, { - "internalType": "uint256", - "name": "", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vToken", + "name": "beacon", "type": "address" } ], - "name": "getUnderlyingPrice", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "accessControlManager_", + "name": "implementation", "type": "address" } ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vankrBNB_LiquidStakedBNB": { + "address": "0x57a664Dd7f1dE19545fEE9c86C949e3BF43d6D47", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "", + "name": "beacon", "type": "address" }, { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "observations", - "outputs": [ + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" }, { - "internalType": "uint256", - "name": "acc", - "type": "uint256" + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "AdminChanged", + "type": "event" }, { - "inputs": [], - "name": "owner", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "beacon", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { - "inputs": [], - "name": "pendingOwner", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "", + "name": "implementation", "type": "address" } ], - "stateMutability": "view", - "type": "function" + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "VToken_vstkBNB_LiquidStakedBNB": { + "address": "0x75aa42c832a8911B77219DbeBABBB40040d16987", + "abi": [ { "inputs": [ { "internalType": "address", - "name": "", + "name": "beacon", "type": "address" - } - ], - "name": "prices", - "outputs": [ + }, { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "stateMutability": "view", - "type": "function" + "stateMutability": "payable", + "type": "constructor" }, { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "accessControlManager_", + "name": "beacon", "type": "address" } ], - "name": "setAccessControlManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "BeaconUpgraded", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "baseUnit", - "type": "uint256" - }, - { - "internalType": "address", - "name": "pancakePool", - "type": "address" - }, - { - "internalType": "bool", - "name": "isBnbBased", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isReversedPool", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" - } - ], - "internalType": "struct TwapOracle.TokenConfig", - "name": "config", - "type": "tuple" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "BinanceOracle": { + "address": "0xB58BFDCE610042311Dc0e034a80Cc7776c1D68f5", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" } ], - "name": "setTokenConfig", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "implementation", + "outputs": [ { - "components": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "baseUnit", - "type": "uint256" - }, - { - "internalType": "address", - "name": "pancakePool", - "type": "address" - }, - { - "internalType": "bool", - "name": "isBnbBased", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isReversedPool", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "anchorPeriod", - "type": "uint256" - } - ], - "internalType": "struct TwapOracle.TokenConfig[]", - "name": "configs", - "type": "tuple[]" + "internalType": "address", + "name": "implementation_", + "type": "address" } ], - "name": "setTokenConfigs", - "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -48756,84 +47959,160 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "newImplementation", "type": "address" } ], - "name": "tokenConfigs", - "outputs": [ + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", - "name": "asset", + "name": "newImplementation", "type": "address" }, { - "internalType": "uint256", - "name": "baseUnit", - "type": "uint256" - }, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ { "internalType": "address", - "name": "pancakePool", + "name": "sender", "type": "address" }, { - "internalType": "bool", - "name": "isBnbBased", - "type": "bool" + "internalType": "address", + "name": "calledContract", + "type": "address" }, { - "internalType": "bool", - "name": "isReversedPool", - "type": "bool" + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "asset", + "type": "string" }, { + "indexed": false, "internalType": "uint256", - "name": "anchorPeriod", + "name": "maxStalePeriod", "type": "uint256" } ], - "stateMutability": "view", - "type": "function" + "name": "MaxStalePeriodAdded", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "newOwner", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", "type": "address" } ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "NewAccessControlManager", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "vToken", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", "type": "address" } ], - "name": "updateTwap", - "outputs": [ + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" } ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "vBnb", + "name": "accessControlManager", "outputs": [ { - "internalType": "address", + "internalType": "contract IAccessControlManagerV8", "name": "", "type": "address" } @@ -48843,7 +48122,7 @@ }, { "inputs": [], - "name": "vai", + "name": "getFeedRegistryAddress", "outputs": [ { "internalType": "address", @@ -48858,11 +48137,11 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "vToken", "type": "address" } ], - "name": "windowStart", + "name": "getUnderlyingPrice", "outputs": [ { "internalType": "uint256", @@ -48872,142 +48151,11932 @@ ], "stateMutability": "view", "type": "function" - } - ] - }, - "TwapOracle_Proxy": { - "address": "0x3eeE05d929D1E9816185B1b6d8c470eC192b4432", - "abi": [ + }, { "inputs": [ { "internalType": "address", - "name": "_logic", + "name": "_sidRegistryAddress", "type": "address" }, { "internalType": "address", - "name": "admin_", + "name": "_accessControlManager", "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" } ], - "stateMutability": "payable", - "type": "constructor" + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "maxStalePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "", "type": "address" } ], - "name": "AdminChanged", - "type": "event" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, - "inputs": [ + "inputs": [], + "name": "pendingOwner", + "outputs": [ { - "indexed": true, "internalType": "address", - "name": "beacon", + "name": "", "type": "address" } ], - "name": "BeaconUpgraded", - "type": "event" + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, "internalType": "address", - "name": "implementation", + "name": "accessControlManager_", "type": "address" } ], - "name": "Upgraded", - "type": "event" + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "stateMutability": "payable", - "type": "fallback" + "inputs": [ + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_maxStalePeriod", + "type": "uint256" + } + ], + "name": "setMaxStalePeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "admin", + "name": "sidRegistryAddress", "outputs": [ { "internalType": "address", - "name": "admin_", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", "type": "address" } ], + "name": "transferOwnership", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "implementation", + "name": "vBnb", "outputs": [ { "internalType": "address", - "name": "implementation_", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "vai", + "outputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "", "type": "address" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", "type": "address" }, { "internalType": "bytes", - "name": "data", + "name": "_data", "type": "bytes" } ], - "name": "upgradeToAndCall", - "outputs": [], "stateMutability": "payable", - "type": "function" + "type": "constructor" + } + ] + }, + "BinanceOracle_Implementation": { + "address": "0xCd64844CD0E8E34782cd0d1bF3E537bf7b474FAe", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "vBnbAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" }, { - "stateMutability": "payable", - "type": "receive" + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "asset", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "name": "MaxStalePeriodAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFeedRegistryAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sidRegistryAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_accessControlManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "maxStalePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_maxStalePeriod", + "type": "uint256" + } + ], + "name": "setMaxStalePeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sidRegistryAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "BinanceOracle_Proxy": { + "address": "0xB58BFDCE610042311Dc0e034a80Cc7776c1D68f5", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "BoundValidator": { + "address": "0x2842140e4Ad3a92e9af30e27e290300dd785076d", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "upperBound", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "lowerBound", + "type": "uint256" + } + ], + "name": "ValidateConfigAdded", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "upperBoundRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lowerBoundRatio", + "type": "uint256" + } + ], + "internalType": "struct BoundValidator.ValidateConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "setValidateConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "upperBoundRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lowerBoundRatio", + "type": "uint256" + } + ], + "internalType": "struct BoundValidator.ValidateConfig[]", + "name": "configs", + "type": "tuple[]" + } + ], + "name": "setValidateConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "validateConfigs", + "outputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "upperBoundRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lowerBoundRatio", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reportedPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "anchorPrice", + "type": "uint256" + } + ], + "name": "validatePriceWithAnchorPrice", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "BoundValidator_Implementation": { + "address": "0x4915F67a57FDcbA22535F0F021D64b66b095d026", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "vBnbAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "upperBound", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "lowerBound", + "type": "uint256" + } + ], + "name": "ValidateConfigAdded", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "upperBoundRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lowerBoundRatio", + "type": "uint256" + } + ], + "internalType": "struct BoundValidator.ValidateConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "setValidateConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "upperBoundRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lowerBoundRatio", + "type": "uint256" + } + ], + "internalType": "struct BoundValidator.ValidateConfig[]", + "name": "configs", + "type": "tuple[]" + } + ], + "name": "setValidateConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "validateConfigs", + "outputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "upperBoundRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lowerBoundRatio", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reportedPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "anchorPrice", + "type": "uint256" + } + ], + "name": "validatePriceWithAnchorPrice", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "BoundValidator_Proxy": { + "address": "0x2842140e4Ad3a92e9af30e27e290300dd785076d", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "ChainlinkOracle": { + "address": "0xCeA29f1266e880A1482c06eD656cD08C148BaA32", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousPriceMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPriceMantissa", + "type": "uint256" + } + ], + "name": "PricePosted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feed", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "name": "setDirectPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "internalType": "struct ChainlinkOracle.TokenConfig", + "name": "tokenConfig", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "internalType": "struct ChainlinkOracle.TokenConfig[]", + "name": "tokenConfigs_", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VBep20Interface", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "underlyingPriceMantissa", + "type": "uint256" + } + ], + "name": "setUnderlyingPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenConfigs", + "outputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "ChainlinkOracle_Implementation": { + "address": "0xa074529FD3d0E7261A730d0f867107BA0C20d74A", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "vBnbAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousPriceMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPriceMantissa", + "type": "uint256" + } + ], + "name": "PricePosted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feed", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "name": "setDirectPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "internalType": "struct ChainlinkOracle.TokenConfig", + "name": "tokenConfig", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "internalType": "struct ChainlinkOracle.TokenConfig[]", + "name": "tokenConfigs_", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VBep20Interface", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "underlyingPriceMantissa", + "type": "uint256" + } + ], + "name": "setUnderlyingPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenConfigs", + "outputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxStalePeriod", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "ChainlinkOracle_Proxy": { + "address": "0xCeA29f1266e880A1482c06eD656cD08C148BaA32", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "DefaultProxyAdmin": { + "address": "0x7877fFd62649b6A1557B55D4c20fcBaB17344C91", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ] + }, + "PythOracle": { + "address": "0x94E1534c14e0736BB24decA625f2F5364B198E0C", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPythOracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPythOracle", + "type": "address" + } + ], + "name": "PythOracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "pythId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "maxStalePeriod", + "type": "uint64" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXP_SCALE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "underlyingPythOracle_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "pythId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint64", + "name": "maxStalePeriod", + "type": "uint64" + } + ], + "internalType": "struct PythOracle.TokenConfig", + "name": "tokenConfig", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "pythId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint64", + "name": "maxStalePeriod", + "type": "uint64" + } + ], + "internalType": "struct PythOracle.TokenConfig[]", + "name": "tokenConfigs_", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IPyth", + "name": "underlyingPythOracle_", + "type": "address" + } + ], + "name": "setUnderlyingPythOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenConfigs", + "outputs": [ + { + "internalType": "bytes32", + "name": "pythId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint64", + "name": "maxStalePeriod", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingPythOracle", + "outputs": [ + { + "internalType": "contract IPyth", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "PythOracle_Implementation": { + "address": "0xb8a450101DF8ab770c8F8521E189a4B39e7Cf5f5", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "vBnbAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPythOracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPythOracle", + "type": "address" + } + ], + "name": "PythOracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "pythId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "maxStalePeriod", + "type": "uint64" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXP_SCALE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "underlyingPythOracle_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "pythId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint64", + "name": "maxStalePeriod", + "type": "uint64" + } + ], + "internalType": "struct PythOracle.TokenConfig", + "name": "tokenConfig", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "pythId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint64", + "name": "maxStalePeriod", + "type": "uint64" + } + ], + "internalType": "struct PythOracle.TokenConfig[]", + "name": "tokenConfigs_", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IPyth", + "name": "underlyingPythOracle_", + "type": "address" + } + ], + "name": "setUnderlyingPythOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenConfigs", + "outputs": [ + { + "internalType": "bytes32", + "name": "pythId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint64", + "name": "maxStalePeriod", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingPythOracle", + "outputs": [ + { + "internalType": "contract IPyth", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "PythOracle_Proxy": { + "address": "0x94E1534c14e0736BB24decA625f2F5364B198E0C", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "ResilientOracle": { + "address": "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "role", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "OracleEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "role", + "type": "uint256" + } + ], + "name": "OracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "mainOracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pivotOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fallbackOracle", + "type": "address" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INVALID_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boundValidator", + "outputs": [ + { + "internalType": "contract BoundValidatorInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "enableOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + } + ], + "name": "getOracle", + "outputs": [ + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getTokenConfig", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + } + ], + "internalType": "struct ResilientOracle.TokenConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + } + ], + "internalType": "struct ResilientOracle.TokenConfig", + "name": "tokenConfig", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + } + ], + "internalType": "struct ResilientOracle.TokenConfig[]", + "name": "tokenConfigs_", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updatePrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "ResilientOracle_Implementation": { + "address": "0xF53cFE89b4c3eFCbdd9aF712e94017454d43c181", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "vBnbAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiAddress", + "type": "address" + }, + { + "internalType": "contract BoundValidatorInterface", + "name": "_boundValidator", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "role", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "OracleEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "role", + "type": "uint256" + } + ], + "name": "OracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "mainOracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pivotOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fallbackOracle", + "type": "address" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INVALID_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boundValidator", + "outputs": [ + { + "internalType": "contract BoundValidatorInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "enableOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + } + ], + "name": "getOracle", + "outputs": [ + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getTokenConfig", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + } + ], + "internalType": "struct ResilientOracle.TokenConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + } + ], + "internalType": "struct ResilientOracle.TokenConfig", + "name": "tokenConfig", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + } + ], + "internalType": "struct ResilientOracle.TokenConfig[]", + "name": "tokenConfigs_", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updatePrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "ResilientOracle_Proxy": { + "address": "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "TwapOracle": { + "address": "0x3eeE05d929D1E9816185B1b6d8c470eC192b4432", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTimestamp", + "type": "uint256" + } + ], + "name": "AnchorPriceUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldAcc", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAcc", + "type": "uint256" + } + ], + "name": "TwapWindowUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_BASE_UNIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BUSD_BASE_UNIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WBNB", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseUnit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBnbBased", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isReversedPool", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "internalType": "struct TwapOracle.TokenConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "currentCumulativePrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "acc", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseUnit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBnbBased", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isReversedPool", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "internalType": "struct TwapOracle.TokenConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseUnit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBnbBased", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isReversedPool", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "internalType": "struct TwapOracle.TokenConfig[]", + "name": "configs", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenConfigs", + "outputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseUnit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBnbBased", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isReversedPool", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateTwap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "windowStart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "TwapOracle_Implementation": { + "address": "0x572ec272B4Ae3a50B99905AFd78671F84474ffd1", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "vBnbAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "wBnbAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTimestamp", + "type": "uint256" + } + ], + "name": "AnchorPriceUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldAcc", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAcc", + "type": "uint256" + } + ], + "name": "TwapWindowUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_BASE_UNIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BUSD_BASE_UNIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WBNB", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseUnit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBnbBased", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isReversedPool", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "internalType": "struct TwapOracle.TokenConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "currentCumulativePrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "acc", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseUnit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBnbBased", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isReversedPool", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "internalType": "struct TwapOracle.TokenConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseUnit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBnbBased", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isReversedPool", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "internalType": "struct TwapOracle.TokenConfig[]", + "name": "configs", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenConfigs", + "outputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseUnit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pancakePool", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBnbBased", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isReversedPool", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "anchorPeriod", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateTwap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "windowStart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "TwapOracle_Proxy": { + "address": "0x3eeE05d929D1E9816185B1b6d8c470eC192b4432", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "GovernorBravoV4": { + "address": "0x4baF88AbA7f86f6540728BEF454b224C5d2215e7", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newGuardian", + "type": "address" + } + ], + "name": "NewGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldImplementation", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "NewImplementation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "ProposalCanceled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "string[]", + "name": "signatures", + "type": "string[]" + }, + { + "indexed": false, + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "description", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "proposalType", + "type": "uint8" + } + ], + "name": "ProposalCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "ProposalExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxOperations", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMaxOperations", + "type": "uint256" + } + ], + "name": "ProposalMaxOperationsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "ProposalQueued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldProposalThreshold", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newProposalThreshold", + "type": "uint256" + } + ], + "name": "ProposalThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "support", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "votes", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "VoteCast", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldVotingDelay", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newVotingDelay", + "type": "uint256" + } + ], + "name": "VotingDelaySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldVotingPeriod", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newVotingPeriod", + "type": "uint256" + } + ], + "name": "VotingPeriodSet", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "BALLOT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_PROPOSAL_THRESHOLD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_VOTING_DELAY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_VOTING_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_PROPOSAL_THRESHOLD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_VOTING_DELAY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_VOTING_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "_acceptAdmin", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "governorAlpha", + "type": "address" + } + ], + "name": "_initiate", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newGuardian", + "type": "address" + } + ], + "name": "_setGuardian", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "_setPendingAdmin", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalMaxOperations_", + "type": "uint256" + } + ], + "name": "_setProposalMaxOperations", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "cancel", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "support", + "type": "uint8" + } + ], + "name": "castVote", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "support", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "castVoteBySig", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "support", + "type": "uint8" + }, + { + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "castVoteWithReason", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "execute", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "getActions", + "outputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "signatures", + "type": "string[]" + }, + { + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "voter", + "type": "address" + } + ], + "name": "getReceipt", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "hasVoted", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "support", + "type": "uint8" + }, + { + "internalType": "uint96", + "name": "votes", + "type": "uint96" + } + ], + "internalType": "struct GovernorBravoDelegateStorageV1.Receipt", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "guardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "initialProposalId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "xvsVault_", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "votingDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "votingPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "proposalThreshold", + "type": "uint256" + } + ], + "internalType": "struct GovernorBravoDelegateStorageV2.ProposalConfig[]", + "name": "proposalConfigs_", + "type": "tuple[]" + }, + { + "internalType": "contract TimelockInterface[]", + "name": "timelocks", + "type": "address[]" + }, + { + "internalType": "address", + "name": "guardian_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "latestProposalIds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "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": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposalConfigs", + "outputs": [ + { + "internalType": "uint256", + "name": "votingDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "votingPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "proposalThreshold", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "proposalCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "proposalMaxOperations", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "proposalThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposalTimelocks", + "outputs": [ + { + "internalType": "contract TimelockInterface", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposals", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "forVotes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "againstVotes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "abstainVotes", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "canceled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "executed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "proposalType", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "signatures", + "type": "string[]" + }, + { + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + }, + { + "internalType": "string", + "name": "description", + "type": "string" + }, + { + "internalType": "enum GovernorBravoDelegateStorageV2.ProposalType", + "name": "proposalType", + "type": "uint8" + } + ], + "name": "propose", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "queue", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "quorumVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "state", + "outputs": [ + { + "internalType": "enum GovernorBravoDelegateStorageV1.ProposalState", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "timelock", + "outputs": [ + { + "internalType": "contract TimelockInterface", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "votingDelay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "votingPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "xvsVault", + "outputs": [ + { + "internalType": "contract XvsVaultInterface", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } + ] + }, + "PegStability_USDT": { + "address": "0xB21E69eef4Bc1D64903fa28D9b32491B1c0786F1", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "AlreadyPaused", + "type": "error" + }, + { + "inputs": [], + "name": "AmountTooSmall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidFee", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughVAI", + "type": "error" + }, + { + "inputs": [], + "name": "NotPaused", + "type": "error" + }, + { + "inputs": [], + "name": "Paused", + "type": "error" + }, + { + "inputs": [], + "name": "TooManyDecimals", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "VAIMintCapReached", + "type": "error" + }, + { + "inputs": [], + "name": "VAIMintedUnderflow", + "type": "error" + }, + { + "inputs": [], + "name": "VAITransferFail", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldFeeIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newFeeIn", + "type": "uint256" + } + ], + "name": "FeeInChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldFeeOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newFeeOut", + "type": "uint256" + } + ], + "name": "FeeOutChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOracle", + "type": "address" + } + ], + "name": "OracleChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "name": "PSMPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "name": "PSMResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "stableIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "vaiOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "StableForVAISwapped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "vaiBurnt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "vaiFee", + "type": "uint256" + } + ], + "name": "VAIForStableSwapped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCap", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCap", + "type": "uint256" + } + ], + "name": "VAIMintCapChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTreasury", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTreasury", + "type": "address" + } + ], + "name": "VenusTreasuryChanged", + "type": "event" + }, + { + "inputs": [], + "name": "BASIS_POINTS_DIVISOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANTISSA_ONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ONE_DOLLAR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STABLE_TOKEN_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VAI", + "outputs": [ + { + "internalType": "contract IVAI", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeIn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, + { + "internalType": "address", + "name": "venusTreasury_", + "type": "address" + }, + { + "internalType": "address", + "name": "oracleAddress_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeIn_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeOut_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vaiMintCap_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "stableTknAmount", + "type": "uint256" + } + ], + "name": "previewSwapStableForVAI", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "stableTknAmount", + "type": "uint256" + } + ], + "name": "previewSwapVAIForStable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resume", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeIn_", + "type": "uint256" + } + ], + "name": "setFeeIn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeOut_", + "type": "uint256" + } + ], + "name": "setFeeOut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oracleAddress_", + "type": "address" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaiMintCap_", + "type": "uint256" + } + ], + "name": "setVAIMintCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "venusTreasury_", + "type": "address" + } + ], + "name": "setVenusTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stableTknAmount", + "type": "uint256" + } + ], + "name": "swapStableForVAI", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stableTknAmount", + "type": "uint256" + } + ], + "name": "swapVAIForStable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vaiMintCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaiMinted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "venusTreasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "PegStability_USDT_Implementation": { + "address": "0xDDa903294fB71141302aD3Bf2AF37dD6Cbd5DBbF", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "stableTokenAddress_", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiAddress_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AlreadyPaused", + "type": "error" + }, + { + "inputs": [], + "name": "AmountTooSmall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidFee", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughVAI", + "type": "error" + }, + { + "inputs": [], + "name": "NotPaused", + "type": "error" + }, + { + "inputs": [], + "name": "Paused", + "type": "error" + }, + { + "inputs": [], + "name": "TooManyDecimals", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "VAIMintCapReached", + "type": "error" + }, + { + "inputs": [], + "name": "VAIMintedUnderflow", + "type": "error" + }, + { + "inputs": [], + "name": "VAITransferFail", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldFeeIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newFeeIn", + "type": "uint256" + } + ], + "name": "FeeInChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldFeeOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newFeeOut", + "type": "uint256" + } + ], + "name": "FeeOutChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOracle", + "type": "address" + } + ], + "name": "OracleChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "name": "PSMPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "name": "PSMResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "stableIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "vaiOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "StableForVAISwapped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "vaiBurnt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "vaiFee", + "type": "uint256" + } + ], + "name": "VAIForStableSwapped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCap", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCap", + "type": "uint256" + } + ], + "name": "VAIMintCapChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTreasury", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTreasury", + "type": "address" + } + ], + "name": "VenusTreasuryChanged", + "type": "event" + }, + { + "inputs": [], + "name": "BASIS_POINTS_DIVISOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANTISSA_ONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ONE_DOLLAR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STABLE_TOKEN_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VAI", + "outputs": [ + { + "internalType": "contract IVAI", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeIn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, + { + "internalType": "address", + "name": "venusTreasury_", + "type": "address" + }, + { + "internalType": "address", + "name": "oracleAddress_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeIn_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeOut_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vaiMintCap_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "stableTknAmount", + "type": "uint256" + } + ], + "name": "previewSwapStableForVAI", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "stableTknAmount", + "type": "uint256" + } + ], + "name": "previewSwapVAIForStable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resume", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeIn_", + "type": "uint256" + } + ], + "name": "setFeeIn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeOut_", + "type": "uint256" + } + ], + "name": "setFeeOut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oracleAddress_", + "type": "address" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaiMintCap_", + "type": "uint256" + } + ], + "name": "setVAIMintCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "venusTreasury_", + "type": "address" + } + ], + "name": "setVenusTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stableTknAmount", + "type": "uint256" + } + ], + "name": "swapStableForVAI", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stableTknAmount", + "type": "uint256" + } + ], + "name": "swapVAIForStable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vaiMintCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaiMinted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "venusTreasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "PegStability_USDT_Proxy": { + "address": "0xB21E69eef4Bc1D64903fa28D9b32491B1c0786F1", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "Timelock_Critical": { + "address": "0x23B893a7C45a5Eb8c8C062b9F32d0D2e43eD286D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "delay_", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "CancelTransaction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "ExecuteTransaction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "newDelay", + "type": "uint256" + } + ], + "name": "NewDelay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "QueueTransaction", + "type": "event" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": true, + "inputs": [], + "name": "GRACE_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAXIMUM_DELAY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_DELAY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "acceptAdmin", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "cancelTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "delay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "executeTransaction", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "queueTransaction", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "queuedTransactions", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "delay_", + "type": "uint256" + } + ], + "name": "setDelay", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "pendingAdmin_", + "type": "address" + } + ], + "name": "setPendingAdmin", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "Timelock_FastTrack": { + "address": "0x3CFf21b7AF8390fE68799D58727d3b4C25a83cb6", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "delay_", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "CancelTransaction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "ExecuteTransaction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "newDelay", + "type": "uint256" + } + ], + "name": "NewDelay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "QueueTransaction", + "type": "event" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": true, + "inputs": [], + "name": "GRACE_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAXIMUM_DELAY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_DELAY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "acceptAdmin", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "cancelTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "delay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "executeTransaction", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "string", + "name": "signature", + "type": "string" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "queueTransaction", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "queuedTransactions", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "delay_", + "type": "uint256" + } + ], + "name": "setDelay", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "pendingAdmin_", + "type": "address" + } + ], + "name": "setPendingAdmin", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "VenusLens": { + "address": "0x11c8dC3DcA87E8205ec01e6d79Be9442d31701d3", + "abi": [ + { + "constant": true, + "inputs": [], + "name": "BLOCKS_PER_DAY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLimits", + "outputs": [ + { + "components": [ + { + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shortfall", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.AccountLimits", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address payable", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "comptrollerAddress", + "type": "address" + } + ], + "name": "getDailyXVS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "contract GovernorAlpha", + "name": "governor", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "proposalIds", + "type": "uint256[]" + } + ], + "name": "getGovProposals", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "eta", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "signatures", + "type": "string[]" + }, + { + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "forVotes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "againstVotes", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "canceled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "executed", + "type": "bool" + } + ], + "internalType": "struct VenusLens.GovProposal[]", + "name": "", + "type": "tuple[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "contract GovernorAlpha", + "name": "governor", + "type": "address" + }, + { + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "proposalIds", + "type": "uint256[]" + } + ], + "name": "getGovReceipts", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "hasVoted", + "type": "bool" + }, + { + "internalType": "bool", + "name": "support", + "type": "bool" + }, + { + "internalType": "uint96", + "name": "votes", + "type": "uint96" + } + ], + "internalType": "struct VenusLens.GovReceipt[]", + "name": "", + "type": "tuple[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "contract XVS", + "name": "xvs", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint32[]", + "name": "blockNumbers", + "type": "uint32[]" + } + ], + "name": "getVenusVotes", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "votes", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.VenusVotes[]", + "name": "", + "type": "tuple[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "contract XVS", + "name": "xvs", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getXVSBalanceMetadata", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "votes", + "type": "uint256" + }, + { + "internalType": "address", + "name": "delegate", + "type": "address" + } + ], + "internalType": "struct VenusLens.XVSBalanceMetadata", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract XVS", + "name": "xvs", + "type": "address" + }, + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getXVSBalanceMetadataExt", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "votes", + "type": "uint256" + }, + { + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocated", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.XVSBalanceMetadataExt", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller", + "type": "address" + } + ], + "name": "pendingRewards", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "distributorAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "vTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.PendingReward[]", + "name": "pendingRewards", + "type": "tuple[]" + } + ], + "internalType": "struct VenusLens.RewardSummary", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address payable", + "name": "account", + "type": "address" + } + ], + "name": "vTokenBalances", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balanceOf", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowBalanceCurrent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceOfUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAllowance", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.VTokenBalances", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "address payable", + "name": "account", + "type": "address" + } + ], + "name": "vTokenBalancesAll", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balanceOf", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowBalanceCurrent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceOfUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAllowance", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.VTokenBalances[]", + "name": "", + "type": "tuple[]" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + } + ], + "name": "vTokenMetadata", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "exchangeRateCurrent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyRatePerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRatePerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlyingAssetAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vTokenDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "venusSupplySpeed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "venusBorrowSpeed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dailySupplyXvs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dailyBorrowXvs", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.VTokenMetadata", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "vTokenMetadataAll", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "exchangeRateCurrent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyRatePerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRatePerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlyingAssetAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vTokenDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "venusSupplySpeed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "venusBorrowSpeed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dailySupplyXvs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dailyBorrowXvs", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.VTokenMetadata[]", + "name": "", + "type": "tuple[]" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + } + ], + "name": "vTokenUnderlyingPrice", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "underlyingPrice", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.VTokenUnderlyingPrice", + "name": "", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "vTokenUnderlyingPriceAll", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "underlyingPrice", + "type": "uint256" + } + ], + "internalType": "struct VenusLens.VTokenUnderlyingPrice[]", + "name": "", + "type": "tuple[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" } ] } diff --git a/deployments/bsctestnet/ProtocolShareReserve.json b/deployments/bsctestnet/ProtocolShareReserve.json new file mode 100644 index 000000000..0c99fe840 --- /dev/null +++ b/deployments/bsctestnet/ProtocolShareReserve.json @@ -0,0 +1,643 @@ +{ + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsReleased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "protocolIncome_", + "type": "address" + }, + { + "internalType": "address", + "name": "riskFund_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolIncome", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "releaseFunds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "transactionIndex": 1, + "gasUsed": "817670", + "logsBloom": "0x10000000000000000000000000000000400000040000000000800008000000000000000000000040000000000000000000000000000001000000000000004000000000000000000000000000000002000001000000001000000000000000000000000008020000000000000000000800000000800000000000000000000000400000000000000000000000000000000000000000000080000000000000800000000000000000000000000000000400000000000000000000000000000000004000000020000000000000000000040000000000000400000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943", + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 33267957, + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000000bbea4b14f475bf5eb60fc2b0ca90d3d089ef833" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943" + }, + { + "transactionIndex": 1, + "blockNumber": 33267957, + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943" + }, + { + "transactionIndex": 1, + "blockNumber": 33267957, + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 2, + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943" + }, + { + "transactionIndex": 1, + "blockNumber": 33267957, + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007877ffd62649b6a1557b55d4c20fcbab17344c91", + "logIndex": 3, + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943" + } + ], + "blockNumber": 33267957, + "cumulativeGasUsed": "848911", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0Bbea4B14f475bF5eb60Fc2b0Ca90d3d089Ef833", + "0x7877fFd62649b6A1557B55D4c20fcBaB17344C91", + "0x485cc9550000000000000000000000008b293600c50d6fbdc6ed4251cc75ece29880276f000000000000000000000000487cef72dacabd7e12e633bb3b63815a386f7012" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": ["0x8b293600C50D6fbdc6Ed4251cc75ECe29880276f", "0x487CeF72dacABD7E12e633bb3B63815a386f7012"] + }, + "implementation": "0x0Bbea4B14f475bF5eb60Fc2b0Ca90d3d089Ef833", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsctestnet/ProtocolShareReserve_Implementation.json b/deployments/bsctestnet/ProtocolShareReserve_Implementation.json new file mode 100644 index 000000000..003b40eda --- /dev/null +++ b/deployments/bsctestnet/ProtocolShareReserve_Implementation.json @@ -0,0 +1,711 @@ +{ + "address": "0x0Bbea4B14f475bF5eb60Fc2b0Ca90d3d089Ef833", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsReleased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "protocolIncome_", + "type": "address" + }, + { + "internalType": "address", + "name": "riskFund_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolIncome", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "releaseFunds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xeb588de1914c19fd30e93f35342a9d0f19152bfb99aaee209179065c17cf4235", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0x0Bbea4B14f475bF5eb60Fc2b0Ca90d3d089Ef833", + "transactionIndex": 2, + "gasUsed": "1213372", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000040000000000000000000000000000000000000000020000000000000000", + "blockHash": "0x019959c7a75adaec5bc40cb888ad52c0539a19496e9d70f5cca2e1aaf613cd61", + "transactionHash": "0xeb588de1914c19fd30e93f35342a9d0f19152bfb99aaee209179065c17cf4235", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 33267950, + "transactionHash": "0xeb588de1914c19fd30e93f35342a9d0f19152bfb99aaee209179065c17cf4235", + "address": "0x0Bbea4B14f475bF5eb60Fc2b0Ca90d3d089Ef833", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 1, + "blockHash": "0x019959c7a75adaec5bc40cb888ad52c0539a19496e9d70f5cca2e1aaf613cd61" + } + ], + "blockNumber": 33267950, + "cumulativeGasUsed": "1325695", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "394b060e0e484d4aa39aea929deecf07", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AssetsReservesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsReleased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPoolRegistry\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPoolRegistry\",\"type\":\"address\"}],\"name\":\"PoolRegistryUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"SweepToken\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetsReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getPoolAssetReserve\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"protocolIncome_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"riskFund_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolIncome\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"releaseFunds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"riskFund\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"name\":\"setPoolRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sweepToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"updateAssetsState\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"getPoolAssetReserve(address,address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"asset\":\"Asset address.\",\"comptroller\":\"Comptroller address(pool).\"},\"returns\":{\"_0\":\"Asset's reserve in risk fund.\"}},\"initialize(address,address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when protocol income address is zeroZeroAddressNotAllowed is thrown when risk fund address is zero\",\"params\":{\"protocolIncome_\":\"The address protocol income will be sent to\",\"riskFund_\":\"Risk fund address\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"releaseFunds(address,address,uint256)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"amount\":\"Amount to release\",\"asset\":\"Asset to be released\",\"comptroller\":\"Pool's Comptroller\"},\"returns\":{\"_0\":\"Number of total released tokens\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setPoolRegistry(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"params\":{\"poolRegistry_\":\"Address of the pool registry\"}},\"sweepToken(address,address)\":{\"custom:access\":\"Only Owner\",\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"_to\":\"Recipient of the output tokens.\",\"_token\":\"The address of the BEP-20 token to sweep\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"updateAssetsState(address,address)\":{\"params\":{\"asset\":\"Asset address.\",\"comptroller\":\"Comptroller address(pool)\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"AssetsReservesUpdated(address,address,uint256)\":{\"notice\":\"Event emitted after the update of the assets reserves.\"},\"FundsReleased(address,address,uint256)\":{\"notice\":\"Emitted when funds are released\"},\"PoolRegistryUpdated(address,address)\":{\"notice\":\"Emitted when pool registry address is updated\"},\"SweepToken(address,address,uint256)\":{\"notice\":\"event emitted on sweep token success\"}},\"kind\":\"user\",\"methods\":{\"getPoolAssetReserve(address,address)\":{\"notice\":\"Get the Amount of the asset in the risk fund for the specific pool.\"},\"initialize(address,address)\":{\"notice\":\"Initializes the deployer to owner.\"},\"releaseFunds(address,address,uint256)\":{\"notice\":\"Release funds\"},\"setPoolRegistry(address)\":{\"notice\":\"Pool registry setter.\"},\"sweepToken(address,address)\":{\"notice\":\"A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\"},\"updateAssetsState(address,address)\":{\"notice\":\"Update the reserve of the asset for the specific pool after transferring to the protocol share reserve.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RiskFund/ProtocolShareReserve.sol\":\"ProtocolShareReserve\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x40031b19684ca0c912e794d08c2c0b0d8be77d3c1bdc937830a0658eff899650\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 badDebt = VToken(vToken).badDebt();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x73fdb4e4b2a2cfec75b0ef5a19491c4136a7953e1239989fb77ed26c1b7a77ac\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title PoolRegistryInterface\\n * @author Venus\\n * @notice Interface implemented by `PoolRegistry`.\\n */\\ninterface PoolRegistryInterface {\\n /**\\n * @notice Struct for a Venus interest rate pool.\\n */\\n struct VenusPool {\\n string name;\\n address creator;\\n address comptroller;\\n uint256 blockPosted;\\n uint256 timestampPosted;\\n }\\n\\n /**\\n * @notice Struct for a Venus interest rate pool metadata.\\n */\\n struct VenusPoolMetaData {\\n string category;\\n string logoURL;\\n string description;\\n }\\n\\n /// @notice Get all pools in PoolRegistry\\n function getAllPools() external view returns (VenusPool[] memory);\\n\\n /// @notice Get a pool by comptroller address\\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\\n\\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\\n\\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\\n\\n /// @notice Get the metadata of a Pool by comptroller address\\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\\n}\\n\",\"keccak256\":\"0x7e8ccd190ef019a3f8c3fcb67ed3eadd7bed32b263f88566870d138cd95ae312\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n // The block number at which to stop rewards\\n uint32 lastRewardingBlock;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n /// @notice Emitted when a reward token last rewarding block for supply is updated\\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n */\\n function setLastRewardingBlocks(\\n VToken[] calldata vTokens,\\n uint32[] calldata supplyLastRewardingBlocks,\\n uint32[] calldata borrowLastRewardingBlocks\\n ) external {\\n _checkAccessAllowed(\\\"setLastRewardingBlock(address[],uint32[],uint32[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ) {\\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for a single market.\\n * @param vToken market's whose reward token last rewarding block to be updated\\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n */\\n function _setLastRewardingBlock(\\n VToken vToken,\\n uint32 supplyLastRewardingBlock,\\n uint32 borrowLastRewardingBlock\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n uint256 blockNumber = getBlockNumber();\\n\\n require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n require(\\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n require(\\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n\\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n }\\n\\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\\n blockNumber = supplyState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\\n blockNumber = borrowState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0x0e5bede4edc4346e689de0adcf98dc9642feb55d44c1916715741c5937a34d52\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IRiskFund.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IRiskFund\\n * @author Venus\\n * @notice Interface implemented by `RiskFund`.\\n */\\ninterface IRiskFund {\\n function swapPoolsAssets(\\n address[] calldata markets,\\n uint256[] calldata amountsOutMin,\\n address[][] calldata paths,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\\n\\n function updateAssetsState(address comptroller, address asset) external;\\n\\n function convertibleBaseAsset() external view returns (address);\\n\\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xa519791948d96fb81143cdd9db0a2b753a39f1f9ca4e8c68b92997e2095f241a\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/ProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\nimport { IProtocolShareReserve } from \\\"./IProtocolShareReserve.sol\\\";\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { ReserveHelpers } from \\\"./ReserveHelpers.sol\\\";\\nimport { IRiskFund } from \\\"./IRiskFund.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\n\\ncontract ProtocolShareReserve is ExponentialNoError, ReserveHelpers, IProtocolShareReserve {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n address public protocolIncome;\\n address public riskFund;\\n // Percentage of funds not sent to the RiskFund contract when the funds are released, following the project Tokenomics\\n uint256 private constant PROTOCOL_SHARE_PERCENTAGE = 50;\\n uint256 private constant BASE_UNIT = 100;\\n\\n /// @notice Emitted when funds are released\\n event FundsReleased(address indexed comptroller, address indexed asset, uint256 amount);\\n\\n /// @notice Emitted when pool registry address is updated\\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializes the deployer to owner.\\n * @param protocolIncome_ The address protocol income will be sent to\\n * @param riskFund_ Risk fund address\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol income address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\\n */\\n function initialize(address protocolIncome_, address riskFund_) external initializer {\\n ensureNonzeroAddress(protocolIncome_);\\n ensureNonzeroAddress(riskFund_);\\n\\n __Ownable2Step_init();\\n\\n protocolIncome = protocolIncome_;\\n riskFund = riskFund_;\\n }\\n\\n /**\\n * @notice Pool registry setter.\\n * @param poolRegistry_ Address of the pool registry\\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n */\\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\\n ensureNonzeroAddress(poolRegistry_);\\n address oldPoolRegistry = poolRegistry;\\n poolRegistry = poolRegistry_;\\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\\n }\\n\\n /**\\n * @notice Release funds\\n * @param comptroller Pool's Comptroller\\n * @param asset Asset to be released\\n * @param amount Amount to release\\n * @return Number of total released tokens\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function releaseFunds(\\n address comptroller,\\n address asset,\\n uint256 amount\\n ) external nonReentrant returns (uint256) {\\n ensureNonzeroAddress(asset);\\n require(amount <= _poolsAssetsReserves[comptroller][asset], \\\"ProtocolShareReserve: Insufficient pool balance\\\");\\n\\n assetsReserves[asset] -= amount;\\n _poolsAssetsReserves[comptroller][asset] -= amount;\\n uint256 protocolIncomeAmount = mul_(\\n Exp({ mantissa: amount }),\\n div_(Exp({ mantissa: PROTOCOL_SHARE_PERCENTAGE * EXP_SCALE }), BASE_UNIT)\\n ).mantissa;\\n\\n address riskFund_ = riskFund;\\n\\n emit FundsReleased(comptroller, asset, amount);\\n\\n IERC20Upgradeable(asset).safeTransfer(protocolIncome, protocolIncomeAmount);\\n IERC20Upgradeable(asset).safeTransfer(riskFund_, amount - protocolIncomeAmount);\\n\\n // Update the pool asset's state in the risk fund for the above transfer.\\n IRiskFund(riskFund_).updateAssetsState(comptroller, asset);\\n\\n return amount;\\n }\\n\\n /**\\n * @notice Update the reserve of the asset for the specific pool after transferring to the protocol share reserve.\\n * @param comptroller Comptroller address(pool)\\n * @param asset Asset address.\\n */\\n function updateAssetsState(address comptroller, address asset)\\n public\\n override(IProtocolShareReserve, ReserveHelpers)\\n {\\n super.updateAssetsState(comptroller, asset);\\n }\\n}\\n\",\"keccak256\":\"0x871a26ce46666f37ff88034dec23d0bb9497b057a861bfd35b166a3ea3e4c785\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/ReserveHelpers.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\nimport { ComptrollerInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { PoolRegistryInterface } from \\\"../Pool/PoolRegistryInterface.sol\\\";\\n\\ncontract ReserveHelpers is Ownable2StepUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 private constant NOT_ENTERED = 1;\\n\\n uint256 private constant ENTERED = 2;\\n\\n // Store the previous state for the asset transferred to ProtocolShareReserve combined(for all pools).\\n mapping(address => uint256) public assetsReserves;\\n\\n // Store the asset's reserve per pool in the ProtocolShareReserve.\\n // Comptroller(pool) -> Asset -> amount\\n mapping(address => mapping(address => uint256)) internal _poolsAssetsReserves;\\n\\n // Address of pool registry contract\\n address public poolRegistry;\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n uint256 internal status;\\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 */\\n uint256[46] private __gap;\\n\\n /// @notice Event emitted after the update of the assets reserves.\\n /// @param comptroller Pool's Comptroller address\\n /// @param asset Token address\\n /// @param amount An amount by which the reserves have increased\\n event AssetsReservesUpdated(address indexed comptroller, address indexed asset, uint256 amount);\\n\\n /// @notice event emitted on sweep token success\\n event SweepToken(address indexed token, address indexed to, uint256 amount);\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(status != ENTERED, \\\"re-entered\\\");\\n status = ENTERED;\\n _;\\n status = NOT_ENTERED;\\n }\\n\\n /**\\n * @notice A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\\n * @param _token The address of the BEP-20 token to sweep\\n * @param _to Recipient of the output tokens.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n * @custom:access Only Owner\\n */\\n function sweepToken(address _token, address _to) external onlyOwner nonReentrant {\\n ensureNonzeroAddress(_to);\\n uint256 balanceDfference_;\\n uint256 balance_ = IERC20Upgradeable(_token).balanceOf(address(this));\\n\\n require(balance_ > assetsReserves[_token], \\\"ReserveHelpers: Zero surplus tokens\\\");\\n unchecked {\\n balanceDfference_ = balance_ - assetsReserves[_token];\\n }\\n\\n emit SweepToken(_token, _to, balanceDfference_);\\n IERC20Upgradeable(_token).safeTransfer(_to, balanceDfference_);\\n }\\n\\n /**\\n * @notice Get the Amount of the asset in the risk fund for the specific pool.\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n * @return Asset's reserve in risk fund.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function getPoolAssetReserve(address comptroller, address asset) external view returns (uint256) {\\n ensureNonzeroAddress(asset);\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"ReserveHelpers: Comptroller address invalid\\\");\\n return _poolsAssetsReserves[comptroller][asset];\\n }\\n\\n /**\\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund\\n * and transferring funds to the protocol share reserve\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function updateAssetsState(address comptroller, address asset) public virtual {\\n ensureNonzeroAddress(asset);\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"ReserveHelpers: Comptroller address invalid\\\");\\n address poolRegistry_ = poolRegistry;\\n require(poolRegistry_ != address(0), \\\"ReserveHelpers: Pool Registry address is not set\\\");\\n require(\\n PoolRegistryInterface(poolRegistry_).getVTokenForAsset(comptroller, asset) != address(0),\\n \\\"ReserveHelpers: The pool doesn't support the asset\\\"\\n );\\n\\n uint256 currentBalance = IERC20Upgradeable(asset).balanceOf(address(this));\\n uint256 assetReserve = assetsReserves[asset];\\n if (currentBalance > assetReserve) {\\n uint256 balanceDifference;\\n unchecked {\\n balanceDifference = currentBalance - assetReserve;\\n }\\n assetsReserves[asset] += balanceDifference;\\n _poolsAssetsReserves[comptroller][asset] += balanceDifference;\\n emit AssetsReservesUpdated(comptroller, asset, balanceDifference);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x689e7d9481b9a86b421de41ad87459e92146c5f2e00ac041b853ee3ad14e4bdf\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611480806100ec6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637b77cd6a11610097578063aac59a7511610066578063aac59a75146101ed578063afcff50f14610200578063e30c397814610213578063f2fde38b1461022457600080fd5b80637b77cd6a146101a35780637cf89030146101b65780638bbdf2af146101c95780638da5cb5b146101dc57600080fd5b8063485cc955116100d3578063485cc9551461016d5780636fb0527514610180578063715018a61461019357806379ba50971461019b57600080fd5b80630e3e3e3a146100fa578063258836fe1461012a578063439b55171461013f575b600080fd5b60c95461010d906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d6101383660046111c0565b610237565b005b61015f61014d3660046111f9565b60976020526000908152604090205481565b604051908152602001610121565b61013d61017b3660046111c0565b6103ea565b61015f61018e3660046111c0565b61053f565b61013d6105f3565b61013d610607565b61013d6101b13660046111f9565b610681565b60ca5461010d906001600160a01b031681565b61015f6101d7366004611216565b6106e4565b6033546001600160a01b031661010d565b61013d6101fb3660046111c0565b610968565b60995461010d906001600160a01b031681565b6065546001600160a01b031661010d565b61013d6102323660046111f9565b610976565b61023f6109e7565b6002609a54036102835760405162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b60448201526064015b60405180910390fd5b6002609a5561029181610a41565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156102da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102fe9190611257565b6001600160a01b03851660009081526097602052604090205490915081116103745760405162461bcd60e51b815260206004820152602360248201527f5265736572766548656c706572733a205a65726f20737572706c757320746f6b604482015262656e7360e81b606482015260840161027a565b6001600160a01b038481166000818152609760209081526040918290205491519185038083529550928616927f6d25be279134f4ecaa4770aff0c3d916d9e7c5ef37b65ed95dbdba411f5d54d5910160405180910390a36103df6001600160a01b0385168484610a68565b50506001609a555050565b600054610100900460ff161580801561040a5750600054600160ff909116105b806104245750303b158015610424575060005460ff166001145b6104875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161027a565b6000805460ff1916600117905580156104aa576000805461ff0019166101001790555b6104b383610a41565b6104bc82610a41565b6104c4610aba565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca805492851692909116919091179055801561053a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061054a82610a41565b826001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ab9190611270565b6105c75760405162461bcd60e51b815260040161027a90611292565b506001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b6105fb6109e7565b6106056000610ae9565b565b60655433906001600160a01b031681146106755760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161027a565b61067e81610ae9565b50565b6106896109e7565b61069281610a41565b609980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b60006002609a54036107255760405162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015260640161027a565b6002609a5561073383610a41565b6001600160a01b038085166000908152609860209081526040808320938716835292905220548211156107c05760405162461bcd60e51b815260206004820152602f60248201527f50726f746f636f6c5368617265526573657276653a20496e737566666963696560448201526e6e7420706f6f6c2062616c616e636560881b606482015260840161027a565b6001600160a01b038316600090815260976020526040812080548492906107e89084906112f3565b90915550506001600160a01b038085166000908152609860209081526040808320938716835292905290812080548492906108249084906112f3565b92505081905550600061087060405180602001604052808581525061086b6040518060200160405280670de0b6b3a76400006032610862919061130a565b90526064610b02565b610b33565b5160ca546040518581529192506001600160a01b0390811691868216918816907feed10c470424824e4a4309075162f10b9989088b23fbed2349698cedd44493fb9060200160405180910390a360c9546108d7906001600160a01b03878116911684610a68565b6108f6816108e584876112f3565b6001600160a01b0388169190610a68565b60405163aac59a7560e01b81526001600160a01b038781166004830152868116602483015282169063aac59a7590604401600060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b50506001609a5550939695505050505050565b6109728282610b72565b5050565b61097e6109e7565b606580546001600160a01b0383166001600160a01b031990911681179091556109af6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b031633146106055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161027a565b6001600160a01b03811661067e576040516342bcdf7f60e11b815260040160405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261053a908490610ea5565b600054610100900460ff16610ae15760405162461bcd60e51b815260040161027a90611329565b610605610f7a565b606580546001600160a01b031916905561067e81610faa565b6040805160208101909152600081526040518060200160405280610b2a856000015185610ffc565b90529392505050565b6040805160208101909152600081526040518060200160405280670de0b6b3a7640000610b688660000151866000015161100f565b610b2a9190611374565b610b7b81610a41565b816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdc9190611270565b610bf85760405162461bcd60e51b815260040161027a90611292565b6099546001600160a01b031680610c6a5760405162461bcd60e51b815260206004820152603060248201527f5265736572766548656c706572733a20506f6f6c20526567697374727920616460448201526f191c995cdcc81a5cc81b9bdd081cd95d60821b606482015260840161027a565b60405163266e0a7f60e01b81526001600160a01b03848116600483015283811660248301526000919083169063266e0a7f90604401602060405180830381865afa158015610cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce09190611396565b6001600160a01b031603610d515760405162461bcd60e51b815260206004820152603260248201527f5265736572766548656c706572733a2054686520706f6f6c20646f65736e2774604482015271081cdd5c1c1bdc9d081d1a1948185cdcd95d60721b606482015260840161027a565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbc9190611257565b6001600160a01b03841660009081526097602052604090205490915080821115610e9e576001600160a01b0384166000908152609760205260408120805483850392839291610e0c9084906113b3565b90915550506001600160a01b03808716600090815260986020908152604080832093891683529290529081208054839290610e489084906113b3565b92505081905550846001600160a01b0316866001600160a01b03167fc39e3e80c0219fde334a8cb5d8468b628482e23388b6e809c90cb00c63c8ce3883604051610e9491815260200190565b60405180910390a3505b5050505050565b6000610efa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661101b9092919063ffffffff16565b9050805160001480610f1b575080806020019051810190610f1b9190611270565b61053a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161027a565b600054610100900460ff16610fa15760405162461bcd60e51b815260040161027a90611329565b61060533610ae9565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006110088284611374565b9392505050565b6000611008828461130a565b606061102a8484600085611032565b949350505050565b6060824710156110935760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161027a565b600080866001600160a01b031685876040516110af91906113fb565b60006040518083038185875af1925050503d80600081146110ec576040519150601f19603f3d011682016040523d82523d6000602084013e6110f1565b606091505b50915091506111028783838761110d565b979650505050505050565b6060831561117c578251600003611175576001600160a01b0385163b6111755760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161027a565b508161102a565b61102a83838151156111915781518083602001fd5b8060405162461bcd60e51b815260040161027a9190611417565b6001600160a01b038116811461067e57600080fd5b600080604083850312156111d357600080fd5b82356111de816111ab565b915060208301356111ee816111ab565b809150509250929050565b60006020828403121561120b57600080fd5b8135611008816111ab565b60008060006060848603121561122b57600080fd5b8335611236816111ab565b92506020840135611246816111ab565b929592945050506040919091013590565b60006020828403121561126957600080fd5b5051919050565b60006020828403121561128257600080fd5b8151801515811461100857600080fd5b6020808252602b908201527f5265736572766548656c706572733a20436f6d7074726f6c6c6572206164647260408201526a195cdcc81a5b9d985b1a5960aa1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611305576113056112dd565b500390565b6000816000190483118215151615611324576113246112dd565b500290565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008261139157634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156113a857600080fd5b8151611008816111ab565b600082198211156113c6576113c66112dd565b500190565b60005b838110156113e65781810151838201526020016113ce565b838111156113f5576000848401525b50505050565b6000825161140d8184602087016113cb565b9190910192915050565b60208152600082518060208401526114368160408501602087016113cb565b601f01601f1916919091016040019291505056fea26469706673582212203e243cb1b5d00b5ce8fca153bc592828d0668926156305aabe1b7e91490ff94664736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80637b77cd6a11610097578063aac59a7511610066578063aac59a75146101ed578063afcff50f14610200578063e30c397814610213578063f2fde38b1461022457600080fd5b80637b77cd6a146101a35780637cf89030146101b65780638bbdf2af146101c95780638da5cb5b146101dc57600080fd5b8063485cc955116100d3578063485cc9551461016d5780636fb0527514610180578063715018a61461019357806379ba50971461019b57600080fd5b80630e3e3e3a146100fa578063258836fe1461012a578063439b55171461013f575b600080fd5b60c95461010d906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61013d6101383660046111c0565b610237565b005b61015f61014d3660046111f9565b60976020526000908152604090205481565b604051908152602001610121565b61013d61017b3660046111c0565b6103ea565b61015f61018e3660046111c0565b61053f565b61013d6105f3565b61013d610607565b61013d6101b13660046111f9565b610681565b60ca5461010d906001600160a01b031681565b61015f6101d7366004611216565b6106e4565b6033546001600160a01b031661010d565b61013d6101fb3660046111c0565b610968565b60995461010d906001600160a01b031681565b6065546001600160a01b031661010d565b61013d6102323660046111f9565b610976565b61023f6109e7565b6002609a54036102835760405162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b60448201526064015b60405180910390fd5b6002609a5561029181610a41565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156102da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102fe9190611257565b6001600160a01b03851660009081526097602052604090205490915081116103745760405162461bcd60e51b815260206004820152602360248201527f5265736572766548656c706572733a205a65726f20737572706c757320746f6b604482015262656e7360e81b606482015260840161027a565b6001600160a01b038481166000818152609760209081526040918290205491519185038083529550928616927f6d25be279134f4ecaa4770aff0c3d916d9e7c5ef37b65ed95dbdba411f5d54d5910160405180910390a36103df6001600160a01b0385168484610a68565b50506001609a555050565b600054610100900460ff161580801561040a5750600054600160ff909116105b806104245750303b158015610424575060005460ff166001145b6104875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161027a565b6000805460ff1916600117905580156104aa576000805461ff0019166101001790555b6104b383610a41565b6104bc82610a41565b6104c4610aba565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca805492851692909116919091179055801561053a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061054a82610a41565b826001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ab9190611270565b6105c75760405162461bcd60e51b815260040161027a90611292565b506001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b6105fb6109e7565b6106056000610ae9565b565b60655433906001600160a01b031681146106755760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161027a565b61067e81610ae9565b50565b6106896109e7565b61069281610a41565b609980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b60006002609a54036107255760405162461bcd60e51b815260206004820152600a6024820152691c994b595b9d195c995960b21b604482015260640161027a565b6002609a5561073383610a41565b6001600160a01b038085166000908152609860209081526040808320938716835292905220548211156107c05760405162461bcd60e51b815260206004820152602f60248201527f50726f746f636f6c5368617265526573657276653a20496e737566666963696560448201526e6e7420706f6f6c2062616c616e636560881b606482015260840161027a565b6001600160a01b038316600090815260976020526040812080548492906107e89084906112f3565b90915550506001600160a01b038085166000908152609860209081526040808320938716835292905290812080548492906108249084906112f3565b92505081905550600061087060405180602001604052808581525061086b6040518060200160405280670de0b6b3a76400006032610862919061130a565b90526064610b02565b610b33565b5160ca546040518581529192506001600160a01b0390811691868216918816907feed10c470424824e4a4309075162f10b9989088b23fbed2349698cedd44493fb9060200160405180910390a360c9546108d7906001600160a01b03878116911684610a68565b6108f6816108e584876112f3565b6001600160a01b0388169190610a68565b60405163aac59a7560e01b81526001600160a01b038781166004830152868116602483015282169063aac59a7590604401600060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b50506001609a5550939695505050505050565b6109728282610b72565b5050565b61097e6109e7565b606580546001600160a01b0383166001600160a01b031990911681179091556109af6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b031633146106055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161027a565b6001600160a01b03811661067e576040516342bcdf7f60e11b815260040160405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261053a908490610ea5565b600054610100900460ff16610ae15760405162461bcd60e51b815260040161027a90611329565b610605610f7a565b606580546001600160a01b031916905561067e81610faa565b6040805160208101909152600081526040518060200160405280610b2a856000015185610ffc565b90529392505050565b6040805160208101909152600081526040518060200160405280670de0b6b3a7640000610b688660000151866000015161100f565b610b2a9190611374565b610b7b81610a41565b816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdc9190611270565b610bf85760405162461bcd60e51b815260040161027a90611292565b6099546001600160a01b031680610c6a5760405162461bcd60e51b815260206004820152603060248201527f5265736572766548656c706572733a20506f6f6c20526567697374727920616460448201526f191c995cdcc81a5cc81b9bdd081cd95d60821b606482015260840161027a565b60405163266e0a7f60e01b81526001600160a01b03848116600483015283811660248301526000919083169063266e0a7f90604401602060405180830381865afa158015610cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce09190611396565b6001600160a01b031603610d515760405162461bcd60e51b815260206004820152603260248201527f5265736572766548656c706572733a2054686520706f6f6c20646f65736e2774604482015271081cdd5c1c1bdc9d081d1a1948185cdcd95d60721b606482015260840161027a565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbc9190611257565b6001600160a01b03841660009081526097602052604090205490915080821115610e9e576001600160a01b0384166000908152609760205260408120805483850392839291610e0c9084906113b3565b90915550506001600160a01b03808716600090815260986020908152604080832093891683529290529081208054839290610e489084906113b3565b92505081905550846001600160a01b0316866001600160a01b03167fc39e3e80c0219fde334a8cb5d8468b628482e23388b6e809c90cb00c63c8ce3883604051610e9491815260200190565b60405180910390a3505b5050505050565b6000610efa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661101b9092919063ffffffff16565b9050805160001480610f1b575080806020019051810190610f1b9190611270565b61053a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161027a565b600054610100900460ff16610fa15760405162461bcd60e51b815260040161027a90611329565b61060533610ae9565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006110088284611374565b9392505050565b6000611008828461130a565b606061102a8484600085611032565b949350505050565b6060824710156110935760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161027a565b600080866001600160a01b031685876040516110af91906113fb565b60006040518083038185875af1925050503d80600081146110ec576040519150601f19603f3d011682016040523d82523d6000602084013e6110f1565b606091505b50915091506111028783838761110d565b979650505050505050565b6060831561117c578251600003611175576001600160a01b0385163b6111755760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161027a565b508161102a565b61102a83838151156111915781518083602001fd5b8060405162461bcd60e51b815260040161027a9190611417565b6001600160a01b038116811461067e57600080fd5b600080604083850312156111d357600080fd5b82356111de816111ab565b915060208301356111ee816111ab565b809150509250929050565b60006020828403121561120b57600080fd5b8135611008816111ab565b60008060006060848603121561122b57600080fd5b8335611236816111ab565b92506020840135611246816111ab565b929592945050506040919091013590565b60006020828403121561126957600080fd5b5051919050565b60006020828403121561128257600080fd5b8151801515811461100857600080fd5b6020808252602b908201527f5265736572766548656c706572733a20436f6d7074726f6c6c6572206164647260408201526a195cdcc81a5b9d985b1a5960aa1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611305576113056112dd565b500390565b6000816000190483118215151615611324576113246112dd565b500290565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008261139157634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156113a857600080fd5b8151611008816111ab565b600082198211156113c6576113c66112dd565b500190565b60005b838110156113e65781810151838201526020016113ce565b838111156113f5576000848401525b50505050565b6000825161140d8184602087016113cb565b9190910192915050565b60208152600082518060208401526114368160408501602087016113cb565b601f01601f1916919091016040019291505056fea26469706673582212203e243cb1b5d00b5ce8fca153bc592828d0668926156305aabe1b7e91490ff94664736f6c634300080d0033", + "devdoc": { + "kind": "dev", + "methods": { + "acceptOwnership()": { + "details": "The new owner accepts the ownership transfer." + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "getPoolAssetReserve(address,address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "asset": "Asset address.", + "comptroller": "Comptroller address(pool)." + }, + "returns": { + "_0": "Asset's reserve in risk fund." + } + }, + "initialize(address,address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when protocol income address is zeroZeroAddressNotAllowed is thrown when risk fund address is zero", + "params": { + "protocolIncome_": "The address protocol income will be sent to", + "riskFund_": "Risk fund address" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pendingOwner()": { + "details": "Returns the address of the pending owner." + }, + "releaseFunds(address,address,uint256)": { + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "amount": "Amount to release", + "asset": "Asset to be released", + "comptroller": "Pool's Comptroller" + }, + "returns": { + "_0": "Number of total released tokens" + } + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "setPoolRegistry(address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when pool registry address is zero", + "params": { + "poolRegistry_": "Address of the pool registry" + } + }, + "sweepToken(address,address)": { + "custom:access": "Only Owner", + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "_to": "Recipient of the output tokens.", + "_token": "The address of the BEP-20 token to sweep" + } + }, + "transferOwnership(address)": { + "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." + }, + "updateAssetsState(address,address)": { + "params": { + "asset": "Asset address.", + "comptroller": "Comptroller address(pool)" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "ZeroAddressNotAllowed()": [ + { + "notice": "Thrown if the supplied address is a zero address where it is not allowed" + } + ] + }, + "events": { + "AssetsReservesUpdated(address,address,uint256)": { + "notice": "Event emitted after the update of the assets reserves." + }, + "FundsReleased(address,address,uint256)": { + "notice": "Emitted when funds are released" + }, + "PoolRegistryUpdated(address,address)": { + "notice": "Emitted when pool registry address is updated" + }, + "SweepToken(address,address,uint256)": { + "notice": "event emitted on sweep token success" + } + }, + "kind": "user", + "methods": { + "getPoolAssetReserve(address,address)": { + "notice": "Get the Amount of the asset in the risk fund for the specific pool." + }, + "initialize(address,address)": { + "notice": "Initializes the deployer to owner." + }, + "releaseFunds(address,address,uint256)": { + "notice": "Release funds" + }, + "setPoolRegistry(address)": { + "notice": "Pool registry setter." + }, + "sweepToken(address,address)": { + "notice": "A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input" + }, + "updateAssetsState(address,address)": { + "notice": "Update the reserve of the asset for the specific pool after transferring to the protocol share reserve." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 290, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 293, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1397, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 162, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 282, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 71, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_pendingOwner", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 150, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 13338, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "assetsReserves", + "offset": 0, + "slot": "151", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 13344, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "_poolsAssetsReserves", + "offset": 0, + "slot": "152", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 13346, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "poolRegistry", + "offset": 0, + "slot": "153", + "type": "t_address" + }, + { + "astId": 13349, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "status", + "offset": 0, + "slot": "154", + "type": "t_uint256" + }, + { + "astId": 13354, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "__gap", + "offset": 0, + "slot": "155", + "type": "t_array(t_uint256)46_storage" + }, + { + "astId": 13101, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "protocolIncome", + "offset": 0, + "slot": "201", + "type": "t_address" + }, + { + "astId": 13103, + "contract": "contracts/RiskFund/ProtocolShareReserve.sol:ProtocolShareReserve", + "label": "riskFund", + "offset": 0, + "slot": "202", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)46_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[46]", + "numberOfBytes": "1472" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} diff --git a/deployments/bsctestnet/ProtocolShareReserve_Proxy.json b/deployments/bsctestnet/ProtocolShareReserve_Proxy.json new file mode 100644 index 000000000..87f72679c --- /dev/null +++ b/deployments/bsctestnet/ProtocolShareReserve_Proxy.json @@ -0,0 +1,257 @@ +{ + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "transactionIndex": 1, + "gasUsed": "817670", + "logsBloom": "0x10000000000000000000000000000000400000040000000000800008000000000000000000000040000000000000000000000000000001000000000000004000000000000000000000000000000002000001000000001000000000000000000000000008020000000000000000000800000000800000000000000000000000400000000000000000000000000000000000000000000080000000000000800000000000000000000000000000000400000000000000000000000000000000004000000020000000000000000000040000000000000400000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943", + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 33267957, + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000000bbea4b14f475bf5eb60fc2b0ca90d3d089ef833" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943" + }, + { + "transactionIndex": 1, + "blockNumber": 33267957, + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943" + }, + { + "transactionIndex": 1, + "blockNumber": 33267957, + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 2, + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943" + }, + { + "transactionIndex": 1, + "blockNumber": 33267957, + "transactionHash": "0xe0ff17919e19d8e44e50d647288f605fdff215295c89f394c5a4f069d2ad15b4", + "address": "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007877ffd62649b6a1557b55d4c20fcbab17344c91", + "logIndex": 3, + "blockHash": "0x50c0fad5b3f68f8dabd9788b5613c7cc0d5a0485220f4eb90a19054bb7174943" + } + ], + "blockNumber": 33267957, + "cumulativeGasUsed": "848911", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0Bbea4B14f475bF5eb60Fc2b0Ca90d3d089Ef833", + "0x7877fFd62649b6A1557B55D4c20fcBaB17344C91", + "0x485cc9550000000000000000000000008b293600c50d6fbdc6ed4251cc75ece29880276f000000000000000000000000487cef72dacabd7e12e633bb3b63815a386f7012" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsctestnet/RiskFund.json b/deployments/bsctestnet/RiskFund.json new file mode 100644 index 000000000..9e77934d6 --- /dev/null +++ b/deployments/bsctestnet/RiskFund.json @@ -0,0 +1,1037 @@ +{ + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ApproveFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldConvertibleBaseAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newConvertibleBaseAsset", + "type": "address" + } + ], + "name": "ConvertibleBaseAssetUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinAmountToConvert", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinAmountToConvert", + "type": "uint256" + } + ], + "name": "MinAmountToConvertUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPancakeSwapRouter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPancakeSwapRouter", + "type": "address" + } + ], + "name": "PancakeSwapRouterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldShortfallContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newShortfallContract", + "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + } + ], + "name": "SwappedPoolsAssets", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredReserveForAuction", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convertibleBaseAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "convertibleBaseAsset_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAmountToConvert", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pancakeSwapRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convertibleBaseAsset", + "type": "address" + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + } + ], + "name": "setMinAmountToConvert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + } + ], + "name": "setPancakeSwapRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "shortfallContractAddress_", + "type": "address" + } + ], + "name": "setShortfallContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "internalType": "address[][]", + "name": "paths", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapPoolsAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferReserveForAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "transactionIndex": 2, + "gasUsed": "888546", + "logsBloom": "0x1000000000000000000000000000000040000000000000000080000800000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000000000000000000000000000081000000000000800000000000000000800000002000008400000000000000800000000000000000002000000020000000000000000001040000000000004400000000000000000020000000000200000000000000002000000000000800000000000000000000000000", + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e", + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000665085ecc7bc1b59c9872d030f2bd6c724739709" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", + "logIndex": 3, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 4, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 5, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007877ffd62649b6a1557b55d4c20fcbab17344c91", + "logIndex": 6, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + } + ], + "blockNumber": 33267915, + "cumulativeGasUsed": "1000882", + "status": 1, + "byzantium": true + }, + "args": [ + "0x665085EcC7bc1B59c9872d030f2Bd6c724739709", + "0x7877fFd62649b6A1557B55D4c20fcBaB17344C91", + "0x2a1d054700000000000000000000000083edf1dee1b730b7e8e13c00ba76027d63a51ac00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000a11c8d9dc9b66e209ef60f0c8d969d3cd988782c00000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa0000000000000000000000000000000000000000000000000000000000000064" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0x83edf1deE1B730b7e8e13C00ba76027D63a51ac0", + "10000000000000000000", + "0xA11c8D9DC9b66E209Ef60F0C8D969D3CD988782c", + "0x45f8a08F534f34A97187626E05d4b6648Eeaa9AA", + 100 + ] + }, + "implementation": "0x665085EcC7bc1B59c9872d030f2Bd6c724739709", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsctestnet/RiskFund_Implementation.json b/deployments/bsctestnet/RiskFund_Implementation.json new file mode 100644 index 000000000..f8d81b0fb --- /dev/null +++ b/deployments/bsctestnet/RiskFund_Implementation.json @@ -0,0 +1,1256 @@ +{ + "address": "0x665085EcC7bc1B59c9872d030f2Bd6c724739709", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ApproveFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetsReservesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldConvertibleBaseAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newConvertibleBaseAsset", + "type": "address" + } + ], + "name": "ConvertibleBaseAssetUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinAmountToConvert", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinAmountToConvert", + "type": "uint256" + } + ], + "name": "MinAmountToConvertUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPancakeSwapRouter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPancakeSwapRouter", + "type": "address" + } + ], + "name": "PancakeSwapRouterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldShortfallContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newShortfallContract", + "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + } + ], + "name": "SwappedPoolsAssets", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredReserveForAuction", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "assetsReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convertibleBaseAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolAssetReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "convertibleBaseAsset_", + "type": "address" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minAmountToConvert", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pancakeSwapRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convertibleBaseAsset", + "type": "address" + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minAmountToConvert_", + "type": "uint256" + } + ], + "name": "setMinAmountToConvert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pancakeSwapRouter_", + "type": "address" + } + ], + "name": "setPancakeSwapRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "setPoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "shortfallContractAddress_", + "type": "address" + } + ], + "name": "setShortfallContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amountsOutMin", + "type": "uint256[]" + }, + { + "internalType": "address[][]", + "name": "paths", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapPoolsAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferReserveForAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetsState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x955a0c232779cfb36d81d2cc7109fca5904681646f40d398cc1102cfc4fbd8da", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0x665085EcC7bc1B59c9872d030f2Bd6c724739709", + "transactionIndex": 3, + "gasUsed": "2577667", + "logsBloom": "0x00000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000200000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0bfdfcabefa0274c2074eb92a0b32ca60efd5db3ae2823d5f14ef82b0bf71782", + "transactionHash": "0x955a0c232779cfb36d81d2cc7109fca5904681646f40d398cc1102cfc4fbd8da", + "logs": [ + { + "transactionIndex": 3, + "blockNumber": 33267908, + "transactionHash": "0x955a0c232779cfb36d81d2cc7109fca5904681646f40d398cc1102cfc4fbd8da", + "address": "0x665085EcC7bc1B59c9872d030f2Bd6c724739709", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 1, + "blockHash": "0x0bfdfcabefa0274c2074eb92a0b32ca60efd5db3ae2823d5f14ef82b0bf71782" + } + ], + "blockNumber": 33267908, + "cumulativeGasUsed": "5977795", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "394b060e0e484d4aa39aea929deecf07", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ApproveFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopsLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredLoops\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"calledContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"methodSignature\",\"type\":\"string\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AssetsReservesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldConvertibleBaseAsset\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newConvertibleBaseAsset\",\"type\":\"address\"}],\"name\":\"ConvertibleBaseAssetUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMaxLoopsLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newmaxLoopsLimit\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMinAmountToConvert\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMinAmountToConvert\",\"type\":\"uint256\"}],\"name\":\"MinAmountToConvertUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPancakeSwapRouter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPancakeSwapRouter\",\"type\":\"address\"}],\"name\":\"PancakeSwapRouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPoolRegistry\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPoolRegistry\",\"type\":\"address\"}],\"name\":\"PoolRegistryUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldShortfallContract\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newShortfallContract\",\"type\":\"address\"}],\"name\":\"ShortfallContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"markets\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"amountsOutMin\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalAmount\",\"type\":\"uint256\"}],\"name\":\"SwappedPoolsAssets\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"SweepToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferredReserveForAuction\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetsReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"convertibleBaseAsset\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getPoolAssetReserve\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"}],\"name\":\"getPoolsBaseAssetReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pancakeSwapRouter_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minAmountToConvert_\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"convertibleBaseAsset_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"loopsLimit_\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLoopsLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minAmountToConvert\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pancakeSwapRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_convertibleBaseAsset\",\"type\":\"address\"}],\"name\":\"setConvertibleBaseAsset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setMaxLoopsLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minAmountToConvert_\",\"type\":\"uint256\"}],\"name\":\"setMinAmountToConvert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pancakeSwapRouter_\",\"type\":\"address\"}],\"name\":\"setPancakeSwapRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"name\":\"setPoolRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"shortfallContractAddress_\",\"type\":\"address\"}],\"name\":\"setShortfallContractAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shortfall\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"markets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amountsOutMin\",\"type\":\"uint256[]\"},{\"internalType\":\"address[][]\",\"name\":\"paths\",\"type\":\"address[][]\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"name\":\"swapPoolsAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sweepToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferReserveForAuction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"updateAssetsState\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This contract does not support BNB.\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"Note that the contract is upgradeable. Use initialize() or reinitializers to set the state variables.\"},\"getPoolAssetReserve(address,address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"asset\":\"Asset address.\",\"comptroller\":\"Comptroller address(pool).\"},\"returns\":{\"_0\":\"Asset's reserve in risk fund.\"}},\"getPoolsBaseAssetReserves(address)\":{\"params\":{\"comptroller\":\"Comptroller address(pool).\"},\"returns\":{\"_0\":\"Base Asset's reserve in risk fund.\"}},\"initialize(address,uint256,address,address,uint256)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when PCS router address is zeroZeroAddressNotAllowed is thrown when convertible base asset address is zero\",\"params\":{\"accessControlManager_\":\"Address of the access control contract\",\"convertibleBaseAsset_\":\"Address of the base asset\",\"loopsLimit_\":\"Limit for the loops in the contract to avoid DOS\",\"minAmountToConvert_\":\"Minimum amount assets must be worth to convert into base asset\",\"pancakeSwapRouter_\":\"Address of the PancakeSwap router\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewAccessControlManager event\",\"details\":\"Admin function to set address of AccessControlManager\",\"params\":{\"accessControlManager_\":\"The new address of the AccessControlManager\"}},\"setConvertibleBaseAsset(address)\":{\"params\":{\"_convertibleBaseAsset\":\"Address for new convertible base asset.\"}},\"setMaxLoopsLimit(uint256)\":{\"params\":{\"limit\":\"Limit for the max loops can execute at a time\"}},\"setMinAmountToConvert(uint256)\":{\"params\":{\"minAmountToConvert_\":\"Min amount to convert.\"}},\"setPancakeSwapRouter(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when PCS router address is zero\",\"params\":{\"pancakeSwapRouter_\":\"Address of the PancakeSwap router\"}},\"setPoolRegistry(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"params\":{\"poolRegistry_\":\"Address of the pool registry\"}},\"setShortfallContractAddress(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when shortfall contract address is zero\",\"params\":{\"shortfallContractAddress_\":\"Address of the auction contract\"}},\"swapPoolsAssets(address[],uint256[],address[][],uint256)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured\",\"params\":{\"amountsOutMin\":\"Minimum amount to receive for swap\",\"deadline\":\"Deadline for the swap\",\"markets\":\"Array of vTokens whose assets to swap for base asset\",\"paths\":\"A path consisting of PCS token pairs for each swap\"},\"returns\":{\"_0\":\"Number of swapped tokens\"}},\"sweepToken(address,address)\":{\"custom:access\":\"Only Owner\",\"custom:error\":\"ZeroAddressNotAllowed is thrown when asset address is zero\",\"params\":{\"_to\":\"Recipient of the output tokens.\",\"_token\":\"The address of the BEP-20 token to sweep\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"transferReserveForAuction(address,uint256)\":{\"params\":{\"amount\":\"Amount to be transferred to auction contract.\",\"comptroller\":\"Comptroller of the pool.\"},\"returns\":{\"_0\":\"Number reserved tokens.\"}},\"updateAssetsState(address,address)\":{\"params\":{\"asset\":\"Asset address.\",\"comptroller\":\"Comptroller address(pool).\"}}},\"title\":\"RiskFund\",\"version\":1},\"userdoc\":{\"errors\":{\"ApproveFailed()\":[{\"notice\":\"Thrown if a contract is unable to approve a transfer\"}],\"MaxLoopsLimitExceeded(uint256,uint256)\":[{\"notice\":\"Thrown an error on maxLoopsLimit exceeds for any loop\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"Thrown when the action is prohibited by AccessControlManager\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"AssetsReservesUpdated(address,address,uint256)\":{\"notice\":\"Event emitted after the update of the assets reserves.\"},\"ConvertibleBaseAssetUpdated(address,address)\":{\"notice\":\"Emitted when convertible base asset is updated\"},\"MaxLoopsLimitUpdated(uint256,uint256)\":{\"notice\":\"Emitted when max loops limit is set\"},\"MinAmountToConvertUpdated(uint256,uint256)\":{\"notice\":\"Emitted when minimum amount to convert is updated\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when access control manager contract address is changed\"},\"PancakeSwapRouterUpdated(address,address)\":{\"notice\":\"Emitted when PancakeSwap router contract address is updated\"},\"PoolRegistryUpdated(address,address)\":{\"notice\":\"Emitted when pool registry address is updated\"},\"ShortfallContractUpdated(address,address)\":{\"notice\":\"Emitted when shortfall contract address is updated\"},\"SwappedPoolsAssets(address[],uint256[],uint256)\":{\"notice\":\"Emitted when pools assets are swapped\"},\"SweepToken(address,address,uint256)\":{\"notice\":\"event emitted on sweep token success\"},\"TransferredReserveForAuction(address,uint256)\":{\"notice\":\"Emitted when reserves are transferred for auction\"}},\"kind\":\"user\",\"methods\":{\"accessControlManager()\":{\"notice\":\"Returns the address of the access control manager contract\"},\"getPoolAssetReserve(address,address)\":{\"notice\":\"Get the Amount of the asset in the risk fund for the specific pool.\"},\"getPoolsBaseAssetReserves(address)\":{\"notice\":\"Get the Amount of the Base asset in the risk fund for the specific pool.\"},\"initialize(address,uint256,address,address,uint256)\":{\"notice\":\"Initializes the deployer to owner.\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of AccessControlManager\"},\"setConvertibleBaseAsset(address)\":{\"notice\":\"Sets a new convertible base asset\"},\"setMaxLoopsLimit(uint256)\":{\"notice\":\"Set the limit for the loops can iterate to avoid the DOS\"},\"setMinAmountToConvert(uint256)\":{\"notice\":\"Min amount to convert setter\"},\"setPancakeSwapRouter(address)\":{\"notice\":\"PancakeSwap router address setter\"},\"setPoolRegistry(address)\":{\"notice\":\"Pool registry setter\"},\"setShortfallContractAddress(address)\":{\"notice\":\"Shortfall contract address setter\"},\"swapPoolsAssets(address[],uint256[],address[][],uint256)\":{\"notice\":\"Swap array of pool assets into base asset's tokens of at least a minimum amount\"},\"sweepToken(address,address)\":{\"notice\":\"A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\"},\"transferReserveForAuction(address,uint256)\":{\"notice\":\"Transfer tokens for auction.\"},\"updateAssetsState(address,address)\":{\"notice\":\"Update the reserve of the asset for the specific pool after transferring to risk fund.\"}},\"notice\":\"Contract with basic features to track/hold different assets for different Comptrollers.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RiskFund/RiskFund.sol\":\"RiskFund\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x40031b19684ca0c912e794d08c2c0b0d8be77d3c1bdc937830a0658eff899650\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 badDebt = VToken(vToken).badDebt();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x73fdb4e4b2a2cfec75b0ef5a19491c4136a7953e1239989fb77ed26c1b7a77ac\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/IPancakeswapV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface IPancakeswapV2Router {\\n function swapExactTokensForTokens(\\n uint256 amountIn,\\n uint256 amountOutMin,\\n address[] calldata path,\\n address to,\\n uint256 deadline\\n ) external returns (uint256[] memory amounts);\\n}\\n\",\"keccak256\":\"0x7e4d140bd2a5671389ad7a3975b65d05a4f750daf6a61c16139d123d9782b96e\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { PoolRegistryInterface } from \\\"./PoolRegistryInterface.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\n\\n/**\\n * @title PoolRegistry\\n * @author Venus\\n * @notice The Isolated Pools architecture centers around the `PoolRegistry` contract. The `PoolRegistry` maintains a directory of isolated lending\\n * pools and can perform actions like creating and registering new pools, adding new markets to existing pools, setting and updating the pool's required\\n * metadata, and providing the getter methods to get information on the pools.\\n *\\n * Isolated lending has three main components: PoolRegistry, pools, and markets. The PoolRegistry is responsible for managing pools.\\n * It can create new pools, update pool metadata and manage markets within pools. PoolRegistry contains getter methods to get the details of\\n * any existing pool like `getVTokenForAsset` and `getPoolsSupportedByAsset`. It also contains methods for updating pool metadata (`updatePoolMetadata`)\\n * and setting pool name (`setPoolName`).\\n *\\n * The directory of pools is managed through two mappings: `_poolByComptroller` which is a hashmap with the comptroller address as the key and `VenusPool` as\\n * the value and `_poolsByID` which is an array of comptroller addresses. Individual pools can be accessed by calling `getPoolByComptroller` with the pool's\\n * comptroller address. `_poolsByID` is used to iterate through all of the pools.\\n *\\n * PoolRegistry also contains a map of asset addresses called `_supportedPools` that maps to an array of assets suppored by each pool. This array of pools by\\n * asset is retrieved by calling `getPoolsSupportedByAsset`.\\n *\\n * PoolRegistry registers new isolated pools in the directory with the `createRegistryPool` method. Isolated pools are composed of independent markets with\\n * specific assets and custom risk management configurations according to their markets.\\n */\\ncontract PoolRegistry is Ownable2StepUpgradeable, AccessControlledV8, PoolRegistryInterface {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct AddMarketInput {\\n VToken vToken;\\n uint256 collateralFactor;\\n uint256 liquidationThreshold;\\n uint256 initialSupply;\\n address vTokenReceiver;\\n uint256 supplyCap;\\n uint256 borrowCap;\\n }\\n\\n uint256 internal constant MAX_POOL_NAME_LENGTH = 100;\\n\\n /**\\n * @notice Maps pool's comptroller address to metadata.\\n */\\n mapping(address => VenusPoolMetaData) public metadata;\\n\\n /**\\n * @dev Maps pool ID to pool's comptroller address\\n */\\n mapping(uint256 => address) private _poolsByID;\\n\\n /**\\n * @dev Total number of pools created.\\n */\\n uint256 private _numberOfPools;\\n\\n /**\\n * @dev Maps comptroller address to Venus pool Index.\\n */\\n mapping(address => VenusPool) private _poolByComptroller;\\n\\n /**\\n * @dev Maps pool's comptroller address to asset to vToken.\\n */\\n mapping(address => mapping(address => address)) private _vTokens;\\n\\n /**\\n * @dev Maps asset to list of supported pools.\\n */\\n mapping(address => address[]) private _supportedPools;\\n\\n /**\\n * @notice Emitted when a new Venus pool is added to the directory.\\n */\\n event PoolRegistered(address indexed comptroller, VenusPool pool);\\n\\n /**\\n * @notice Emitted when a pool name is set.\\n */\\n event PoolNameSet(address indexed comptroller, string oldName, string newName);\\n\\n /**\\n * @notice Emitted when a pool metadata is updated.\\n */\\n event PoolMetadataUpdated(\\n address indexed comptroller,\\n VenusPoolMetaData oldMetadata,\\n VenusPoolMetaData newMetadata\\n );\\n\\n /**\\n * @notice Emitted when a Market is added to the pool.\\n */\\n event MarketAdded(address indexed comptroller, address indexed vTokenAddress);\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializes the deployer to owner\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(address accessControlManager_) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n /**\\n * @notice Adds a new Venus pool to the directory\\n * @dev Price oracle must be configured before adding a pool\\n * @param name The name of the pool\\n * @param comptroller Pool's Comptroller contract\\n * @param closeFactor The pool's close factor (scaled by 1e18)\\n * @param liquidationIncentive The pool's liquidation incentive (scaled by 1e18)\\n * @param minLiquidatableCollateral Minimal collateral for regular (non-batch) liquidations flow\\n * @return index The index of the registered Venus pool\\n * @custom:error ZeroAddressNotAllowed is thrown when Comptroller address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when price oracle address is zero\\n */\\n function addPool(\\n string calldata name,\\n Comptroller comptroller,\\n uint256 closeFactor,\\n uint256 liquidationIncentive,\\n uint256 minLiquidatableCollateral\\n ) external virtual returns (uint256 index) {\\n _checkAccessAllowed(\\\"addPool(string,address,uint256,uint256,uint256)\\\");\\n // Input validation\\n ensureNonzeroAddress(address(comptroller));\\n ensureNonzeroAddress(address(comptroller.oracle()));\\n\\n uint256 poolId = _registerPool(name, address(comptroller));\\n\\n // Set Venus pool parameters\\n comptroller.setCloseFactor(closeFactor);\\n comptroller.setLiquidationIncentive(liquidationIncentive);\\n comptroller.setMinLiquidatableCollateral(minLiquidatableCollateral);\\n\\n return poolId;\\n }\\n\\n /**\\n * @notice Add a market to an existing pool and then mint to provide initial supply\\n * @param input The structure describing the parameters for adding a market to a pool\\n * @custom:error ZeroAddressNotAllowed is thrown when vToken address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when vTokenReceiver address is zero\\n */\\n function addMarket(AddMarketInput memory input) external {\\n _checkAccessAllowed(\\\"addMarket(AddMarketInput)\\\");\\n ensureNonzeroAddress(address(input.vToken));\\n ensureNonzeroAddress(input.vTokenReceiver);\\n require(input.initialSupply > 0, \\\"PoolRegistry: initialSupply is zero\\\");\\n\\n VToken vToken = input.vToken;\\n address vTokenAddress = address(vToken);\\n address comptrollerAddress = address(vToken.comptroller());\\n Comptroller comptroller = Comptroller(comptrollerAddress);\\n address underlyingAddress = vToken.underlying();\\n IERC20Upgradeable underlying = IERC20Upgradeable(underlyingAddress);\\n\\n require(_poolByComptroller[comptrollerAddress].creator != address(0), \\\"PoolRegistry: Pool not registered\\\");\\n // solhint-disable-next-line reason-string\\n require(\\n _vTokens[comptrollerAddress][underlyingAddress] == address(0),\\n \\\"PoolRegistry: Market already added for asset comptroller combination\\\"\\n );\\n\\n comptroller.supportMarket(vToken);\\n comptroller.setCollateralFactor(vToken, input.collateralFactor, input.liquidationThreshold);\\n\\n uint256[] memory newSupplyCaps = new uint256[](1);\\n uint256[] memory newBorrowCaps = new uint256[](1);\\n VToken[] memory vTokens = new VToken[](1);\\n\\n newSupplyCaps[0] = input.supplyCap;\\n newBorrowCaps[0] = input.borrowCap;\\n vTokens[0] = vToken;\\n\\n comptroller.setMarketSupplyCaps(vTokens, newSupplyCaps);\\n comptroller.setMarketBorrowCaps(vTokens, newBorrowCaps);\\n\\n _vTokens[comptrollerAddress][underlyingAddress] = vTokenAddress;\\n _supportedPools[underlyingAddress].push(comptrollerAddress);\\n\\n uint256 amountToSupply = _transferIn(underlying, msg.sender, input.initialSupply);\\n underlying.approve(vTokenAddress, 0);\\n underlying.approve(vTokenAddress, amountToSupply);\\n vToken.mintBehalf(input.vTokenReceiver, amountToSupply);\\n\\n emit MarketAdded(comptrollerAddress, vTokenAddress);\\n }\\n\\n /**\\n * @notice Modify existing Venus pool name\\n * @param comptroller Pool's Comptroller\\n * @param name New pool name\\n */\\n function setPoolName(address comptroller, string calldata name) external {\\n _checkAccessAllowed(\\\"setPoolName(address,string)\\\");\\n _ensureValidName(name);\\n VenusPool storage pool = _poolByComptroller[comptroller];\\n string memory oldName = pool.name;\\n pool.name = name;\\n emit PoolNameSet(comptroller, oldName, name);\\n }\\n\\n /**\\n * @notice Update metadata of an existing pool\\n * @param comptroller Pool's Comptroller\\n * @param metadata_ New pool metadata\\n */\\n function updatePoolMetadata(address comptroller, VenusPoolMetaData calldata metadata_) external {\\n _checkAccessAllowed(\\\"updatePoolMetadata(address,VenusPoolMetaData)\\\");\\n VenusPoolMetaData memory oldMetadata = metadata[comptroller];\\n metadata[comptroller] = metadata_;\\n emit PoolMetadataUpdated(comptroller, oldMetadata, metadata_);\\n }\\n\\n /**\\n * @notice Returns arrays of all Venus pools' data\\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\\n * @return A list of all pools within PoolRegistry, with details for each pool\\n */\\n function getAllPools() external view override returns (VenusPool[] memory) {\\n uint256 numberOfPools_ = _numberOfPools; // storage load to save gas\\n VenusPool[] memory _pools = new VenusPool[](numberOfPools_);\\n for (uint256 i = 1; i <= numberOfPools_; ++i) {\\n address comptroller = _poolsByID[i];\\n _pools[i - 1] = (_poolByComptroller[comptroller]);\\n }\\n return _pools;\\n }\\n\\n /**\\n * @param comptroller The comptroller proxy address associated to the pool\\n * @return Returns Venus pool\\n */\\n function getPoolByComptroller(address comptroller) external view override returns (VenusPool memory) {\\n return _poolByComptroller[comptroller];\\n }\\n\\n /**\\n * @param comptroller comptroller of Venus pool\\n * @return Returns Metadata of Venus pool\\n */\\n function getVenusPoolMetadata(address comptroller) external view override returns (VenusPoolMetaData memory) {\\n return metadata[comptroller];\\n }\\n\\n function getVTokenForAsset(address comptroller, address asset) external view override returns (address) {\\n return _vTokens[comptroller][asset];\\n }\\n\\n function getPoolsSupportedByAsset(address asset) external view override returns (address[] memory) {\\n return _supportedPools[asset];\\n }\\n\\n /**\\n * @dev Adds a new Venus pool to the directory (without checking msg.sender).\\n * @param name The name of the pool\\n * @param comptroller The pool's Comptroller proxy contract address\\n * @return The index of the registered Venus pool\\n */\\n function _registerPool(string calldata name, address comptroller) internal returns (uint256) {\\n VenusPool storage storedPool = _poolByComptroller[comptroller];\\n\\n require(storedPool.creator == address(0), \\\"PoolRegistry: Pool already exists in the directory.\\\");\\n _ensureValidName(name);\\n\\n ++_numberOfPools;\\n uint256 numberOfPools_ = _numberOfPools; // cache on stack to save storage read gas\\n\\n VenusPool memory pool = VenusPool(name, msg.sender, comptroller, block.number, block.timestamp);\\n\\n _poolsByID[numberOfPools_] = comptroller;\\n _poolByComptroller[comptroller] = pool;\\n\\n emit PoolRegistered(comptroller, pool);\\n return numberOfPools_;\\n }\\n\\n function _transferIn(\\n IERC20Upgradeable token,\\n address from,\\n uint256 amount\\n ) internal returns (uint256) {\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n return balanceAfter - balanceBefore;\\n }\\n\\n function _ensureValidName(string calldata name) internal pure {\\n require(bytes(name).length <= MAX_POOL_NAME_LENGTH, \\\"Pool's name is too large\\\");\\n }\\n}\\n\",\"keccak256\":\"0x6b903c298c9e2c3aaed29b4a1f76ace9fc24e50a48db22111bfc190a1a25c499\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title PoolRegistryInterface\\n * @author Venus\\n * @notice Interface implemented by `PoolRegistry`.\\n */\\ninterface PoolRegistryInterface {\\n /**\\n * @notice Struct for a Venus interest rate pool.\\n */\\n struct VenusPool {\\n string name;\\n address creator;\\n address comptroller;\\n uint256 blockPosted;\\n uint256 timestampPosted;\\n }\\n\\n /**\\n * @notice Struct for a Venus interest rate pool metadata.\\n */\\n struct VenusPoolMetaData {\\n string category;\\n string logoURL;\\n string description;\\n }\\n\\n /// @notice Get all pools in PoolRegistry\\n function getAllPools() external view returns (VenusPool[] memory);\\n\\n /// @notice Get a pool by comptroller address\\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\\n\\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\\n\\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\\n\\n /// @notice Get the metadata of a Pool by comptroller address\\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\\n}\\n\",\"keccak256\":\"0x7e8ccd190ef019a3f8c3fcb67ed3eadd7bed32b263f88566870d138cd95ae312\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n // The block number at which to stop rewards\\n uint32 lastRewardingBlock;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n /// @notice Emitted when a reward token last rewarding block for supply is updated\\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n */\\n function setLastRewardingBlocks(\\n VToken[] calldata vTokens,\\n uint32[] calldata supplyLastRewardingBlocks,\\n uint32[] calldata borrowLastRewardingBlocks\\n ) external {\\n _checkAccessAllowed(\\\"setLastRewardingBlock(address[],uint32[],uint32[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ) {\\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for a single market.\\n * @param vToken market's whose reward token last rewarding block to be updated\\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n */\\n function _setLastRewardingBlock(\\n VToken vToken,\\n uint32 supplyLastRewardingBlock,\\n uint32 borrowLastRewardingBlock\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n uint256 blockNumber = getBlockNumber();\\n\\n require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n require(\\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n require(\\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n\\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n }\\n\\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\\n blockNumber = supplyState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\\n blockNumber = borrowState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0x0e5bede4edc4346e689de0adcf98dc9642feb55d44c1916715741c5937a34d52\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IRiskFund.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IRiskFund\\n * @author Venus\\n * @notice Interface implemented by `RiskFund`.\\n */\\ninterface IRiskFund {\\n function swapPoolsAssets(\\n address[] calldata markets,\\n uint256[] calldata amountsOutMin,\\n address[][] calldata paths,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\\n\\n function updateAssetsState(address comptroller, address asset) external;\\n\\n function convertibleBaseAsset() external view returns (address);\\n\\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xa519791948d96fb81143cdd9db0a2b753a39f1f9ca4e8c68b92997e2095f241a\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/ReserveHelpers.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\nimport { ComptrollerInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { PoolRegistryInterface } from \\\"../Pool/PoolRegistryInterface.sol\\\";\\n\\ncontract ReserveHelpers is Ownable2StepUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 private constant NOT_ENTERED = 1;\\n\\n uint256 private constant ENTERED = 2;\\n\\n // Store the previous state for the asset transferred to ProtocolShareReserve combined(for all pools).\\n mapping(address => uint256) public assetsReserves;\\n\\n // Store the asset's reserve per pool in the ProtocolShareReserve.\\n // Comptroller(pool) -> Asset -> amount\\n mapping(address => mapping(address => uint256)) internal _poolsAssetsReserves;\\n\\n // Address of pool registry contract\\n address public poolRegistry;\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n uint256 internal status;\\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 */\\n uint256[46] private __gap;\\n\\n /// @notice Event emitted after the update of the assets reserves.\\n /// @param comptroller Pool's Comptroller address\\n /// @param asset Token address\\n /// @param amount An amount by which the reserves have increased\\n event AssetsReservesUpdated(address indexed comptroller, address indexed asset, uint256 amount);\\n\\n /// @notice event emitted on sweep token success\\n event SweepToken(address indexed token, address indexed to, uint256 amount);\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(status != ENTERED, \\\"re-entered\\\");\\n status = ENTERED;\\n _;\\n status = NOT_ENTERED;\\n }\\n\\n /**\\n * @notice A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\\n * @param _token The address of the BEP-20 token to sweep\\n * @param _to Recipient of the output tokens.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n * @custom:access Only Owner\\n */\\n function sweepToken(address _token, address _to) external onlyOwner nonReentrant {\\n ensureNonzeroAddress(_to);\\n uint256 balanceDfference_;\\n uint256 balance_ = IERC20Upgradeable(_token).balanceOf(address(this));\\n\\n require(balance_ > assetsReserves[_token], \\\"ReserveHelpers: Zero surplus tokens\\\");\\n unchecked {\\n balanceDfference_ = balance_ - assetsReserves[_token];\\n }\\n\\n emit SweepToken(_token, _to, balanceDfference_);\\n IERC20Upgradeable(_token).safeTransfer(_to, balanceDfference_);\\n }\\n\\n /**\\n * @notice Get the Amount of the asset in the risk fund for the specific pool.\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n * @return Asset's reserve in risk fund.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function getPoolAssetReserve(address comptroller, address asset) external view returns (uint256) {\\n ensureNonzeroAddress(asset);\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"ReserveHelpers: Comptroller address invalid\\\");\\n return _poolsAssetsReserves[comptroller][asset];\\n }\\n\\n /**\\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund\\n * and transferring funds to the protocol share reserve\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\\n */\\n function updateAssetsState(address comptroller, address asset) public virtual {\\n ensureNonzeroAddress(asset);\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"ReserveHelpers: Comptroller address invalid\\\");\\n address poolRegistry_ = poolRegistry;\\n require(poolRegistry_ != address(0), \\\"ReserveHelpers: Pool Registry address is not set\\\");\\n require(\\n PoolRegistryInterface(poolRegistry_).getVTokenForAsset(comptroller, asset) != address(0),\\n \\\"ReserveHelpers: The pool doesn't support the asset\\\"\\n );\\n\\n uint256 currentBalance = IERC20Upgradeable(asset).balanceOf(address(this));\\n uint256 assetReserve = assetsReserves[asset];\\n if (currentBalance > assetReserve) {\\n uint256 balanceDifference;\\n unchecked {\\n balanceDifference = currentBalance - assetReserve;\\n }\\n assetsReserves[asset] += balanceDifference;\\n _poolsAssetsReserves[comptroller][asset] += balanceDifference;\\n emit AssetsReservesUpdated(comptroller, asset, balanceDifference);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x689e7d9481b9a86b421de41ad87459e92146c5f2e00ac041b853ee3ad14e4bdf\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/RiskFund.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { ComptrollerInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { IRiskFund } from \\\"./IRiskFund.sol\\\";\\nimport { ReserveHelpers } from \\\"./ReserveHelpers.sol\\\";\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { ComptrollerViewInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { PoolRegistry } from \\\"../Pool/PoolRegistry.sol\\\";\\nimport { IPancakeswapV2Router } from \\\"../IPancakeswapV2Router.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\nimport { ApproveOrRevert } from \\\"../lib/ApproveOrRevert.sol\\\";\\n\\n/**\\n * @title RiskFund\\n * @author Venus\\n * @notice Contract with basic features to track/hold different assets for different Comptrollers.\\n * @dev This contract does not support BNB.\\n */\\ncontract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, MaxLoopsLimitHelper, IRiskFund {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using ApproveOrRevert for IERC20Upgradeable;\\n\\n address public convertibleBaseAsset;\\n address public shortfall;\\n address public pancakeSwapRouter;\\n uint256 public minAmountToConvert;\\n\\n /// @notice Emitted when pool registry address is updated\\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\\n\\n /// @notice Emitted when shortfall contract address is updated\\n event ShortfallContractUpdated(address indexed oldShortfallContract, address indexed newShortfallContract);\\n\\n /// @notice Emitted when convertible base asset is updated\\n event ConvertibleBaseAssetUpdated(address indexed oldConvertibleBaseAsset, address indexed newConvertibleBaseAsset);\\n\\n /// @notice Emitted when PancakeSwap router contract address is updated\\n event PancakeSwapRouterUpdated(address indexed oldPancakeSwapRouter, address indexed newPancakeSwapRouter);\\n\\n /// @notice Emitted when minimum amount to convert is updated\\n event MinAmountToConvertUpdated(uint256 oldMinAmountToConvert, uint256 newMinAmountToConvert);\\n\\n /// @notice Emitted when pools assets are swapped\\n event SwappedPoolsAssets(address[] markets, uint256[] amountsOutMin, uint256 totalAmount);\\n\\n /// @notice Emitted when reserves are transferred for auction\\n event TransferredReserveForAuction(address indexed comptroller, uint256 amount);\\n\\n /// @dev Note that the contract is upgradeable. Use initialize() or reinitializers\\n /// to set the state variables.\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializes the deployer to owner.\\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\\n * @param minAmountToConvert_ Minimum amount assets must be worth to convert into base asset\\n * @param convertibleBaseAsset_ Address of the base asset\\n * @param accessControlManager_ Address of the access control contract\\n * @param loopsLimit_ Limit for the loops in the contract to avoid DOS\\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\\n */\\n function initialize(\\n address pancakeSwapRouter_,\\n uint256 minAmountToConvert_,\\n address convertibleBaseAsset_,\\n address accessControlManager_,\\n uint256 loopsLimit_\\n ) external initializer {\\n ensureNonzeroAddress(pancakeSwapRouter_);\\n ensureNonzeroAddress(convertibleBaseAsset_);\\n require(minAmountToConvert_ > 0, \\\"Risk Fund: Invalid min amount to convert\\\");\\n require(loopsLimit_ > 0, \\\"Risk Fund: Loops limit can not be zero\\\");\\n\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n pancakeSwapRouter = pancakeSwapRouter_;\\n minAmountToConvert = minAmountToConvert_;\\n convertibleBaseAsset = convertibleBaseAsset_;\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n /**\\n * @notice Pool registry setter\\n * @param poolRegistry_ Address of the pool registry\\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n */\\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\\n ensureNonzeroAddress(poolRegistry_);\\n address oldPoolRegistry = poolRegistry;\\n poolRegistry = poolRegistry_;\\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\\n }\\n\\n /**\\n * @notice Shortfall contract address setter\\n * @param shortfallContractAddress_ Address of the auction contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n */\\n function setShortfallContractAddress(address shortfallContractAddress_) external onlyOwner {\\n ensureNonzeroAddress(shortfallContractAddress_);\\n\\n address oldShortfallContractAddress = shortfall;\\n shortfall = shortfallContractAddress_;\\n emit ShortfallContractUpdated(oldShortfallContractAddress, shortfallContractAddress_);\\n }\\n\\n /**\\n * @notice PancakeSwap router address setter\\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\\n */\\n function setPancakeSwapRouter(address pancakeSwapRouter_) external onlyOwner {\\n ensureNonzeroAddress(pancakeSwapRouter_);\\n address oldPancakeSwapRouter = pancakeSwapRouter;\\n pancakeSwapRouter = pancakeSwapRouter_;\\n emit PancakeSwapRouterUpdated(oldPancakeSwapRouter, pancakeSwapRouter_);\\n }\\n\\n /**\\n * @notice Min amount to convert setter\\n * @param minAmountToConvert_ Min amount to convert.\\n */\\n function setMinAmountToConvert(uint256 minAmountToConvert_) external {\\n _checkAccessAllowed(\\\"setMinAmountToConvert(uint256)\\\");\\n require(minAmountToConvert_ > 0, \\\"Risk Fund: Invalid min amount to convert\\\");\\n uint256 oldMinAmountToConvert = minAmountToConvert;\\n minAmountToConvert = minAmountToConvert_;\\n emit MinAmountToConvertUpdated(oldMinAmountToConvert, minAmountToConvert_);\\n }\\n\\n /**\\n * @notice Sets a new convertible base asset\\n * @param _convertibleBaseAsset Address for new convertible base asset.\\n */\\n function setConvertibleBaseAsset(address _convertibleBaseAsset) external {\\n _checkAccessAllowed(\\\"setConvertibleBaseAsset(address)\\\");\\n require(_convertibleBaseAsset != address(0), \\\"Risk Fund: new convertible base asset address invalid\\\");\\n\\n address oldConvertibleBaseAsset = convertibleBaseAsset;\\n convertibleBaseAsset = _convertibleBaseAsset;\\n\\n emit ConvertibleBaseAssetUpdated(oldConvertibleBaseAsset, _convertibleBaseAsset);\\n }\\n\\n /**\\n * @notice Swap array of pool assets into base asset's tokens of at least a minimum amount\\n * @param markets Array of vTokens whose assets to swap for base asset\\n * @param amountsOutMin Minimum amount to receive for swap\\n * @param paths A path consisting of PCS token pairs for each swap\\n * @param deadline Deadline for the swap\\n * @return Number of swapped tokens\\n * @custom:error ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured\\n */\\n function swapPoolsAssets(\\n address[] calldata markets,\\n uint256[] calldata amountsOutMin,\\n address[][] calldata paths,\\n uint256 deadline\\n ) external override nonReentrant returns (uint256) {\\n _checkAccessAllowed(\\\"swapPoolsAssets(address[],uint256[],address[][],uint256)\\\");\\n require(deadline >= block.timestamp, \\\"Risk fund: deadline passed\\\");\\n address poolRegistry_ = poolRegistry;\\n ensureNonzeroAddress(poolRegistry_);\\n require(markets.length == amountsOutMin.length, \\\"Risk fund: markets and amountsOutMin are unequal lengths\\\");\\n require(markets.length == paths.length, \\\"Risk fund: markets and paths are unequal lengths\\\");\\n\\n uint256 totalAmount;\\n uint256 marketsCount = markets.length;\\n\\n _ensureMaxLoops(marketsCount);\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n address comptroller = address(VToken(markets[i]).comptroller());\\n\\n PoolRegistry.VenusPool memory pool = PoolRegistry(poolRegistry_).getPoolByComptroller(comptroller);\\n require(pool.comptroller == comptroller, \\\"comptroller doesn't exist pool registry\\\");\\n require(Comptroller(comptroller).isMarketListed(VToken(markets[i])), \\\"market is not listed\\\");\\n\\n uint256 swappedTokens = _swapAsset(VToken(markets[i]), comptroller, amountsOutMin[i], paths[i]);\\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] += swappedTokens;\\n assetsReserves[convertibleBaseAsset] += swappedTokens;\\n totalAmount = totalAmount + swappedTokens;\\n }\\n\\n emit SwappedPoolsAssets(markets, amountsOutMin, totalAmount);\\n\\n return totalAmount;\\n }\\n\\n /**\\n * @notice Transfer tokens for auction.\\n * @param comptroller Comptroller of the pool.\\n * @param amount Amount to be transferred to auction contract.\\n * @return Number reserved tokens.\\n */\\n function transferReserveForAuction(address comptroller, uint256 amount)\\n external\\n override\\n nonReentrant\\n returns (uint256)\\n {\\n address shortfall_ = shortfall;\\n require(msg.sender == shortfall_, \\\"Risk fund: Only callable by Shortfall contract\\\");\\n require(\\n amount <= _poolsAssetsReserves[comptroller][convertibleBaseAsset],\\n \\\"Risk Fund: Insufficient pool reserve.\\\"\\n );\\n unchecked {\\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] =\\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] -\\n amount;\\n }\\n unchecked {\\n assetsReserves[convertibleBaseAsset] = assetsReserves[convertibleBaseAsset] - amount;\\n }\\n\\n emit TransferredReserveForAuction(comptroller, amount);\\n IERC20Upgradeable(convertibleBaseAsset).safeTransfer(shortfall_, amount);\\n\\n return amount;\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Get the Amount of the Base asset in the risk fund for the specific pool.\\n * @param comptroller Comptroller address(pool).\\n * @return Base Asset's reserve in risk fund.\\n */\\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256) {\\n require(ComptrollerInterface(comptroller).isComptroller(), \\\"Risk Fund: Comptroller address invalid\\\");\\n return _poolsAssetsReserves[comptroller][convertibleBaseAsset];\\n }\\n\\n /**\\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund.\\n * @param comptroller Comptroller address(pool).\\n * @param asset Asset address.\\n */\\n function updateAssetsState(address comptroller, address asset) public override(IRiskFund, ReserveHelpers) {\\n super.updateAssetsState(comptroller, asset);\\n }\\n\\n /**\\n * @dev Swap single asset to base asset.\\n * @param vToken VToken\\n * @param comptroller Comptroller address\\n * @param amountOutMin Minimum amount to receive for swap\\n * @param path A path for the swap consisting of PCS token pairs\\n * @return Number of swapped tokens.\\n */\\n function _swapAsset(\\n VToken vToken,\\n address comptroller,\\n uint256 amountOutMin,\\n address[] calldata path\\n ) internal returns (uint256) {\\n require(amountOutMin != 0, \\\"RiskFund: amountOutMin must be greater than 0 to swap vToken\\\");\\n uint256 totalAmount;\\n\\n address underlyingAsset = vToken.underlying();\\n address convertibleBaseAsset_ = convertibleBaseAsset;\\n uint256 balanceOfUnderlyingAsset = _poolsAssetsReserves[comptroller][underlyingAsset];\\n\\n if (balanceOfUnderlyingAsset == 0) {\\n return 0;\\n }\\n\\n ResilientOracleInterface oracle = ComptrollerViewInterface(comptroller).oracle();\\n oracle.updateAssetPrice(convertibleBaseAsset_);\\n Exp memory baseAssetPrice = Exp({ mantissa: oracle.getPrice(convertibleBaseAsset_) });\\n uint256 amountOutMinInUsd = mul_ScalarTruncate(baseAssetPrice, amountOutMin);\\n\\n require(amountOutMinInUsd >= minAmountToConvert, \\\"RiskFund: minAmountToConvert violated\\\");\\n\\n assetsReserves[underlyingAsset] -= balanceOfUnderlyingAsset;\\n _poolsAssetsReserves[comptroller][underlyingAsset] -= balanceOfUnderlyingAsset;\\n\\n if (underlyingAsset != convertibleBaseAsset_) {\\n require(path[0] == underlyingAsset, \\\"RiskFund: swap path must start with the underlying asset\\\");\\n require(\\n path[path.length - 1] == convertibleBaseAsset_,\\n \\\"RiskFund: finally path must be convertible base asset\\\"\\n );\\n address pancakeSwapRouter_ = pancakeSwapRouter;\\n IERC20Upgradeable(underlyingAsset).approveOrRevert(pancakeSwapRouter_, 0);\\n IERC20Upgradeable(underlyingAsset).approveOrRevert(pancakeSwapRouter_, balanceOfUnderlyingAsset);\\n uint256[] memory amounts = IPancakeswapV2Router(pancakeSwapRouter_).swapExactTokensForTokens(\\n balanceOfUnderlyingAsset,\\n amountOutMin,\\n path,\\n address(this),\\n block.timestamp\\n );\\n totalAmount = amounts[path.length - 1];\\n } else {\\n totalAmount = balanceOfUnderlyingAsset;\\n }\\n\\n return totalAmount;\\n }\\n}\\n\",\"keccak256\":\"0xb16c27419547f251890c508ee9244b6515f9fd3c35c8ba82f1b485f50dc854c4\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/ApproveOrRevert.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\nlibrary ApproveOrRevert {\\n /// @notice Thrown if a contract is unable to approve a transfer\\n error ApproveFailed();\\n\\n /// @notice Approves a transfer, ensuring that it is successful. This function supports non-compliant\\n /// tokens like the ones that don't return a boolean value on success. Thus, such approve call supports\\n /// three different kinds of tokens:\\n /// * Compliant tokens that revert on failure\\n /// * Compliant tokens that return false on failure\\n /// * Non-compliant tokens that don't return a value\\n /// @param token The contract address of the token which will be transferred\\n /// @param spender The spender contract address\\n /// @param amount The value of the transfer\\n function approveOrRevert(\\n IERC20Upgradeable token,\\n address spender,\\n uint256 amount\\n ) internal {\\n bytes memory callData = abi.encodeCall(token.approve, (spender, amount));\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory result) = address(token).call(callData);\\n\\n if (!success || (result.length != 0 && !abi.decode(result, (bool)))) {\\n revert ApproveFailed();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x60505497b334ce53f01cdaeedcee4cfc9dfd153b69e9ceecd165282c9bd2c031\",\"license\":\"MIT\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b612d2d80620000f36000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806377d4937f116100f9578063afcff50f11610097578063c8ecc0d311610071578063c8ecc0d31461037b578063e30c39781461038f578063f2fde38b146103a0578063fe3da984146103b357600080fd5b8063afcff50f1461034e578063b4a0bdf314610361578063be26317e1461037257600080fd5b806380d45a2d116100d357806380d45a2d146103045780638da5cb5b14610317578063a69bd19e14610328578063aac59a751461033b57600080fd5b806377d4937f146102d657806379ba5097146102e95780637b77cd6a146102f157600080fd5b80632e688141116101665780635f30e37b116101405780635f30e37b146102955780636fb05275146102a8578063715018a6146102bb578063746460a9146102c357600080fd5b80632e6881411461024f578063439b5517146102625780634dd9584a1461028257600080fd5b80630a9837c5146101ae5780630e32cb86146101d457806319b1faef146101e95780632455899514610215578063258836fe146102295780632a1d05471461023c575b600080fd5b6101c16101bc3660046124a8565b6103bd565b6040519081526020015b60405180910390f35b6101e76101e23660046124d4565b61058c565b005b61012e546101fd906001600160a01b031681565b6040516001600160a01b0390911681526020016101cb565b61012f546101fd906001600160a01b031681565b6101e76102373660046124f1565b6105a0565b6101e761024a36600461252a565b610731565b6101e761025d3660046124d4565b610922565b6101c16102703660046124d4565b60c96020526000908152604090205481565b6101e76102903660046124d4565b610a27565b6101c16102a33660046125d1565b610a8b565b6101c16102b63660046124f1565b610fdf565b6101e7611093565b6101e76102d1366004612674565b6110a7565b6101e76102e43660046124d4565b61114c565b6101e76111b0565b6101e76102ff3660046124d4565b611227565b6101e7610312366004612674565b61128a565b6033546001600160a01b03166101fd565b6101c16103363660046124d4565b61129b565b6101e76103493660046124f1565b611387565b60cb546101fd906001600160a01b031681565b6097546001600160a01b03166101fd565b6101c160fb5481565b61012d546101fd906001600160a01b031681565b6065546001600160a01b03166101fd565b6101e76103ae3660046124d4565b611395565b6101c16101305481565b6000600260cc54036103ea5760405162461bcd60e51b81526004016103e19061268d565b60405180910390fd5b600260cc5561012e546001600160a01b03163381146104625760405162461bcd60e51b815260206004820152602e60248201527f5269736b2066756e643a204f6e6c792063616c6c61626c652062792053686f7260448201526d1d19985b1b0818dbdb9d1c9858dd60921b60648201526084016103e1565b6001600160a01b03808516600090815260ca6020908152604080832061012d54909416835292905220548311156104e95760405162461bcd60e51b815260206004820152602560248201527f5269736b2046756e643a20496e73756666696369656e7420706f6f6c2072657360448201526432b93b329760d91b60648201526084016103e1565b6001600160a01b03808516600081815260ca6020908152604080832061012d80548716855290835281842080548a9003905554909416825260c990528290208054869003905590517fc8d0a37ed16dfaa43514df00e18f478b60d5cc7b4bfc687103948b9020f737fd906105609086815260200190565b60405180910390a261012d54610580906001600160a01b03168285611406565b5050600160cc55919050565b61059461145d565b61059d816114b7565b50565b6105a861145d565b600260cc54036105ca5760405162461bcd60e51b81526004016103e19061268d565b600260cc556105d881611575565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa158015610621573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064591906126b1565b6001600160a01b038516600090815260c9602052604090205490915081116106bb5760405162461bcd60e51b815260206004820152602360248201527f5265736572766548656c706572733a205a65726f20737572706c757320746f6b604482015262656e7360e81b60648201526084016103e1565b6001600160a01b03848116600081815260c960209081526040918290205491519185038083529550928616927f6d25be279134f4ecaa4770aff0c3d916d9e7c5ef37b65ed95dbdba411f5d54d5910160405180910390a36107266001600160a01b0385168484611406565b5050600160cc555050565b600054610100900460ff16158080156107515750600054600160ff909116105b8061076b5750303b15801561076b575060005460ff166001145b6107ce5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103e1565b6000805460ff1916600117905580156107f1576000805461ff0019166101001790555b6107fa86611575565b61080384611575565b600085116108235760405162461bcd60e51b81526004016103e1906126ca565b600082116108825760405162461bcd60e51b815260206004820152602660248201527f5269736b2046756e643a204c6f6f7073206c696d69742063616e206e6f74206260448201526565207a65726f60d01b60648201526084016103e1565b61088a61159c565b610893836115cb565b61012f80546001600160a01b038089166001600160a01b03199283161790925561013087905561012d8054928716929091169190911790556108d4826115f2565b801561091a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6109606040518060400160405280602081526020017f736574436f6e7665727469626c6542617365417373657428616464726573732981525061168c565b6001600160a01b0381166109d45760405162461bcd60e51b815260206004820152603560248201527f5269736b2046756e643a206e657720636f6e7665727469626c65206261736520604482015274185cdcd95d081859191c995cdcc81a5b9d985b1a59605a1b60648201526084016103e1565b61012d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f5fa61583da12070720613fefdd68cc6c0e464a71e009742526bd2b2e0ac62cd290600090a35050565b610a2f61145d565b610a3881611575565b61012f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fd37b9d138f53ea58d7e50292588239a46efa8f523966febf4066da96defc77fd90600090a35050565b6000600260cc5403610aaf5760405162461bcd60e51b81526004016103e19061268d565b600260cc81905550610ad8604051806060016040528060388152602001612cc06038913961168c565b42821015610b285760405162461bcd60e51b815260206004820152601a60248201527f5269736b2066756e643a20646561646c696e652070617373656400000000000060448201526064016103e1565b60cb546001600160a01b0316610b3d81611575565b878614610bb25760405162461bcd60e51b815260206004820152603860248201527f5269736b2066756e643a206d61726b65747320616e6420616d6f756e74734f7560448201527f744d696e2061726520756e657175616c206c656e67746873000000000000000060648201526084016103e1565b878414610c1a5760405162461bcd60e51b815260206004820152603060248201527f5269736b2066756e643a206d61726b65747320616e642070617468732061726560448201526f20756e657175616c206c656e6774687360801b60648201526084016103e1565b600088610c2681611726565b60005b81811015610f8c5760008c8c83818110610c4557610c45612712565b9050602002016020810190610c5a91906124d4565b6001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbb9190612728565b604051637aee632d60e01b81526001600160a01b038083166004830152919250600091871690637aee632d90602401600060405180830381865afa158015610d07573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d2f91908101906127f5565b9050816001600160a01b031681604001516001600160a01b031614610da65760405162461bcd60e51b815260206004820152602760248201527f636f6d7074726f6c6c657220646f65736e277420657869737420706f6f6c20726044820152666567697374727960c81b60648201526084016103e1565b816001600160a01b0316633d98a1e58f8f86818110610dc757610dc7612712565b9050602002016020810190610ddc91906124d4565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4491906128eb565b610e875760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d081a5cc81b9bdd081b1a5cdd195960621b60448201526064016103e1565b6000610ef68f8f86818110610e9e57610e9e612712565b9050602002016020810190610eb391906124d4565b848f8f88818110610ec657610ec6612712565b905060200201358e8e89818110610edf57610edf612712565b9050602002810190610ef1919061290d565b611757565b6001600160a01b03808516600090815260ca6020908152604080832061012d54909416835292905290812080549293508392909190610f3690849061296d565b909155505061012d546001600160a01b0316600090815260c9602052604081208054839290610f6690849061296d565b90915550610f769050818761296d565b955050505080610f8590612985565b9050610c29565b507fb17530966b045b50d4975e7f05048ca00d7335780c24f1c465165a4b94b2d37d8b8b8b8b86604051610fc49594939291906129e7565b60405180910390a150600160cc559998505050505050505050565b6000610fea82611575565b826001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104b91906128eb565b6110675760405162461bcd60e51b81526004016103e190612a42565b506001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b61109b61145d565b6110a56000611cfa565b565b6110e56040518060400160405280601e81526020017f7365744d696e416d6f756e74546f436f6e766572742875696e7432353629000081525061168c565b600081116111055760405162461bcd60e51b81526004016103e1906126ca565b61013080549082905560408051828152602081018490527fada67d0d38fa20c8ae6a5c17cb9d60b0fe7f2d4e4f27ac9ee55e54ac88de9d8d91015b60405180910390a15050565b61115461145d565b61115d81611575565b61012e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fb6e5fcf02f7fbb8acfbaa3bac4fd5abf9ff51e3f2e8884b5498927179b211b2890600090a35050565b60655433906001600160a01b0316811461121e5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016103e1565b61059d81611cfa565b61122f61145d565b61123881611575565b60cb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b61129261145d565b61059d816115f2565b6000816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fe91906128eb565b6113595760405162461bcd60e51b815260206004820152602660248201527f5269736b2046756e643a20436f6d7074726f6c6c6572206164647265737320696044820152651b9d985b1a5960d21b60648201526084016103e1565b506001600160a01b03908116600090815260ca6020908152604080832061012d549094168352929052205490565b6113918282611d13565b5050565b61139d61145d565b606580546001600160a01b0383166001600160a01b031990911681179091556113ce6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611458908490612046565b505050565b6033546001600160a01b031633146110a55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103e1565b6001600160a01b03811661151b5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b60648201526084016103e1565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa09101611140565b6001600160a01b03811661059d576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff166115c35760405162461bcd60e51b81526004016103e190612a8d565b6110a561211b565b600054610100900460ff166105945760405162461bcd60e51b81526004016103e190612a8d565b60fb54811161164e5760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b60648201526084016103e1565b60fb80549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa9101611140565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab906116bf9033908690600401612b04565b602060405180830381865afa1580156116dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170091906128eb565b90508061139157333083604051634a3fa29360e01b81526004016103e193929190612b28565b60fb5481111561059d5760fb5460405163792bfb1b60e11b81526004810191909152602481018290526044016103e1565b6000836000036117cf5760405162461bcd60e51b815260206004820152603c60248201527f5269736b46756e643a20616d6f756e744f75744d696e206d757374206265206760448201527f726561746572207468616e203020746f20737761702076546f6b656e0000000060648201526084016103e1565b600080876001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190612728565b61012d546001600160a01b03898116600090815260ca6020908152604080832084871684529091528120549394509116919081900361187a576000945050505050611cf1565b6000896001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190612728565b60405163b62cad6960e01b81526001600160a01b0385811660048301529192509082169063b62cad6990602401600060405180830381600087803b15801561192557600080fd5b505af1158015611939573d6000803e3d6000fd5b50506040805160208101918290526341976e0960e01b9091526001600160a01b03868116602483015260009350909150819084166341976e0960448301602060405180830381865afa158015611993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b791906126b1565b9052905060006119c7828c61214b565b905061013054811015611a2a5760405162461bcd60e51b815260206004820152602560248201527f5269736b46756e643a206d696e416d6f756e74546f436f6e766572742076696f6044820152641b185d195960da1b60648201526084016103e1565b6001600160a01b038616600090815260c9602052604081208054869290611a52908490612b54565b90915550506001600160a01b03808d16600090815260ca60209081526040808320938a1683529290529081208054869290611a8e908490612b54565b90915550506001600160a01b0386811690861614611ce357856001600160a01b03168a8a6000818110611ac357611ac3612712565b9050602002016020810190611ad891906124d4565b6001600160a01b031614611b545760405162461bcd60e51b815260206004820152603860248201527f5269736b46756e643a20737761702070617468206d757374207374617274207760448201527f6974682074686520756e6465726c79696e67206173736574000000000000000060648201526084016103e1565b6001600160a01b0385168a8a611b6b600182612b54565b818110611b7a57611b7a612712565b9050602002016020810190611b8f91906124d4565b6001600160a01b031614611c035760405162461bcd60e51b815260206004820152603560248201527f5269736b46756e643a2066696e616c6c792070617468206d75737420626520636044820152741bdb9d995c9d1a589b194818985cd948185cdcd95d605a1b60648201526084016103e1565b61012f546001600160a01b0390811690611c2190881682600061216b565b611c356001600160a01b038816828761216b565b6000816001600160a01b03166338ed1739878f8f8f30426040518763ffffffff1660e01b8152600401611c6d96959493929190612b6b565b6000604051808303816000875af1158015611c8c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cb49190810190612ba9565b905080611cc260018d612b54565b81518110611cd257611cd2612712565b602002602001015198505050611ce7565b8396505b5094955050505050505b95945050505050565b606580546001600160a01b031916905561059d81612257565b611d1c81611575565b816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7d91906128eb565b611d995760405162461bcd60e51b81526004016103e190612a42565b60cb546001600160a01b031680611e0b5760405162461bcd60e51b815260206004820152603060248201527f5265736572766548656c706572733a20506f6f6c20526567697374727920616460448201526f191c995cdcc81a5cc81b9bdd081cd95d60821b60648201526084016103e1565b60405163266e0a7f60e01b81526001600160a01b03848116600483015283811660248301526000919083169063266e0a7f90604401602060405180830381865afa158015611e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e819190612728565b6001600160a01b031603611ef25760405162461bcd60e51b815260206004820152603260248201527f5265736572766548656c706572733a2054686520706f6f6c20646f65736e2774604482015271081cdd5c1c1bdc9d081d1a1948185cdcd95d60721b60648201526084016103e1565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5d91906126b1565b6001600160a01b038416600090815260c960205260409020549091508082111561203f576001600160a01b038416600090815260c960205260408120805483850392839291611fad90849061296d565b90915550506001600160a01b03808716600090815260ca6020908152604080832093891683529290529081208054839290611fe990849061296d565b92505081905550846001600160a01b0316866001600160a01b03167fc39e3e80c0219fde334a8cb5d8468b628482e23388b6e809c90cb00c63c8ce388360405161203591815260200190565b60405180910390a3505b5050505050565b600061209b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122a99092919063ffffffff16565b90508051600014806120bc5750808060200190518101906120bc91906128eb565b6114585760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103e1565b600054610100900460ff166121425760405162461bcd60e51b81526004016103e190612a8d565b6110a533611cfa565b60008061215884846122b8565b9050612163816122e9565b949350505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1790529151909160009182918716906121c9908590612c4f565b6000604051808303816000865af19150503d8060008114612206576040519150601f19603f3d011682016040523d82523d6000602084013e61220b565b606091505b5091509150811580612239575080511580159061223957508080602001905181019061223791906128eb565b155b1561091a57604051633e3f8f7360e01b815260040160405180910390fd5b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606121638484600085612307565b60408051602081019091526000815260405180602001604052806122e08560000151856123e2565b90529392505050565b805160009061230190670de0b6b3a764000090612c6b565b92915050565b6060824710156123685760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103e1565b600080866001600160a01b031685876040516123849190612c4f565b60006040518083038185875af1925050503d80600081146123c1576040519150601f19603f3d011682016040523d82523d6000602084013e6123c6565b606091505b50915091506123d7878383876123f5565b979650505050505050565b60006123ee8284612c8d565b9392505050565b6060831561246457825160000361245d576001600160a01b0385163b61245d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103e1565b5081612163565b61216383838151156124795781518083602001fd5b8060405162461bcd60e51b81526004016103e19190612cac565b6001600160a01b038116811461059d57600080fd5b600080604083850312156124bb57600080fd5b82356124c681612493565b946020939093013593505050565b6000602082840312156124e657600080fd5b81356123ee81612493565b6000806040838503121561250457600080fd5b823561250f81612493565b9150602083013561251f81612493565b809150509250929050565b600080600080600060a0868803121561254257600080fd5b853561254d81612493565b945060208601359350604086013561256481612493565b9250606086013561257481612493565b949793965091946080013592915050565b60008083601f84011261259757600080fd5b50813567ffffffffffffffff8111156125af57600080fd5b6020830191508360208260051b85010111156125ca57600080fd5b9250929050565b60008060008060008060006080888a0312156125ec57600080fd5b873567ffffffffffffffff8082111561260457600080fd5b6126108b838c01612585565b909950975060208a013591508082111561262957600080fd5b6126358b838c01612585565b909750955060408a013591508082111561264e57600080fd5b5061265b8a828b01612585565b989b979a50959894979596606090950135949350505050565b60006020828403121561268657600080fd5b5035919050565b6020808252600a90820152691c994b595b9d195c995960b21b604082015260600190565b6000602082840312156126c357600080fd5b5051919050565b60208082526028908201527f5269736b2046756e643a20496e76616c6964206d696e20616d6f756e7420746f6040820152670818dbdb9d995c9d60c21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561273a57600080fd5b81516123ee81612493565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561277e5761277e612745565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156127ad576127ad612745565b604052919050565b60005b838110156127d05781810151838201526020016127b8565b838111156127df576000848401525b50505050565b80516127f081612493565b919050565b6000602080838503121561280857600080fd5b825167ffffffffffffffff8082111561282057600080fd5b9084019060a0828703121561283457600080fd5b61283c61275b565b82518281111561284b57600080fd5b8301601f8101881361285c57600080fd5b80518381111561286e5761286e612745565b612880601f8201601f19168701612784565b9350808452888682840101111561289657600080fd5b6128a5818786018885016127b5565b50508181526128b58484016127e5565b848201526128c5604084016127e5565b604082015260608301516060820152608083015160808201528094505050505092915050565b6000602082840312156128fd57600080fd5b815180151581146123ee57600080fd5b6000808335601e1984360301811261292457600080fd5b83018035915067ffffffffffffffff82111561293f57600080fd5b6020019150600581901b36038213156125ca57600080fd5b634e487b7160e01b600052601160045260246000fd5b6000821982111561298057612980612957565b500190565b60006001820161299757612997612957565b5060010190565b8183526000602080850194508260005b858110156129dc5781356129c181612493565b6001600160a01b0316875295820195908201906001016129ae565b509495945050505050565b6060815260006129fb60608301878961299e565b82810360208401528481526001600160fb1b03851115612a1a57600080fd5b8460051b80876020840137600091016020019081526040929092019290925295945050505050565b6020808252602b908201527f5265736572766548656c706572733a20436f6d7074726f6c6c6572206164647260408201526a195cdcc81a5b9d985b1a5960aa1b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008151808452612af08160208601602086016127b5565b601f01601f19169290920160200192915050565b6001600160a01b038316815260406020820181905260009061216390830184612ad8565b6001600160a01b03848116825283166020820152606060408201819052600090611cf190830184612ad8565b600082821015612b6657612b66612957565b500390565b86815285602082015260a060408201526000612b8b60a08301868861299e565b6001600160a01b039490941660608301525060800152949350505050565b60006020808385031215612bbc57600080fd5b825167ffffffffffffffff80821115612bd457600080fd5b818501915085601f830112612be857600080fd5b815181811115612bfa57612bfa612745565b8060051b9150612c0b848301612784565b8181529183018401918481019088841115612c2557600080fd5b938501935b83851015612c4357845182529385019390850190612c2a565b98975050505050505050565b60008251612c618184602087016127b5565b9190910192915050565b600082612c8857634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612ca757612ca7612957565b500290565b6020815260006123ee6020830184612ad856fe73776170506f6f6c7341737365747328616464726573735b5d2c75696e743235365b5d2c616464726573735b5d5b5d2c75696e7432353629a26469706673582212200df4784c551e6f296a40813ffbdb6c465608d0b9582f5f659a9257b405a4147e64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806377d4937f116100f9578063afcff50f11610097578063c8ecc0d311610071578063c8ecc0d31461037b578063e30c39781461038f578063f2fde38b146103a0578063fe3da984146103b357600080fd5b8063afcff50f1461034e578063b4a0bdf314610361578063be26317e1461037257600080fd5b806380d45a2d116100d357806380d45a2d146103045780638da5cb5b14610317578063a69bd19e14610328578063aac59a751461033b57600080fd5b806377d4937f146102d657806379ba5097146102e95780637b77cd6a146102f157600080fd5b80632e688141116101665780635f30e37b116101405780635f30e37b146102955780636fb05275146102a8578063715018a6146102bb578063746460a9146102c357600080fd5b80632e6881411461024f578063439b5517146102625780634dd9584a1461028257600080fd5b80630a9837c5146101ae5780630e32cb86146101d457806319b1faef146101e95780632455899514610215578063258836fe146102295780632a1d05471461023c575b600080fd5b6101c16101bc3660046124a8565b6103bd565b6040519081526020015b60405180910390f35b6101e76101e23660046124d4565b61058c565b005b61012e546101fd906001600160a01b031681565b6040516001600160a01b0390911681526020016101cb565b61012f546101fd906001600160a01b031681565b6101e76102373660046124f1565b6105a0565b6101e761024a36600461252a565b610731565b6101e761025d3660046124d4565b610922565b6101c16102703660046124d4565b60c96020526000908152604090205481565b6101e76102903660046124d4565b610a27565b6101c16102a33660046125d1565b610a8b565b6101c16102b63660046124f1565b610fdf565b6101e7611093565b6101e76102d1366004612674565b6110a7565b6101e76102e43660046124d4565b61114c565b6101e76111b0565b6101e76102ff3660046124d4565b611227565b6101e7610312366004612674565b61128a565b6033546001600160a01b03166101fd565b6101c16103363660046124d4565b61129b565b6101e76103493660046124f1565b611387565b60cb546101fd906001600160a01b031681565b6097546001600160a01b03166101fd565b6101c160fb5481565b61012d546101fd906001600160a01b031681565b6065546001600160a01b03166101fd565b6101e76103ae3660046124d4565b611395565b6101c16101305481565b6000600260cc54036103ea5760405162461bcd60e51b81526004016103e19061268d565b60405180910390fd5b600260cc5561012e546001600160a01b03163381146104625760405162461bcd60e51b815260206004820152602e60248201527f5269736b2066756e643a204f6e6c792063616c6c61626c652062792053686f7260448201526d1d19985b1b0818dbdb9d1c9858dd60921b60648201526084016103e1565b6001600160a01b03808516600090815260ca6020908152604080832061012d54909416835292905220548311156104e95760405162461bcd60e51b815260206004820152602560248201527f5269736b2046756e643a20496e73756666696369656e7420706f6f6c2072657360448201526432b93b329760d91b60648201526084016103e1565b6001600160a01b03808516600081815260ca6020908152604080832061012d80548716855290835281842080548a9003905554909416825260c990528290208054869003905590517fc8d0a37ed16dfaa43514df00e18f478b60d5cc7b4bfc687103948b9020f737fd906105609086815260200190565b60405180910390a261012d54610580906001600160a01b03168285611406565b5050600160cc55919050565b61059461145d565b61059d816114b7565b50565b6105a861145d565b600260cc54036105ca5760405162461bcd60e51b81526004016103e19061268d565b600260cc556105d881611575565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa158015610621573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064591906126b1565b6001600160a01b038516600090815260c9602052604090205490915081116106bb5760405162461bcd60e51b815260206004820152602360248201527f5265736572766548656c706572733a205a65726f20737572706c757320746f6b604482015262656e7360e81b60648201526084016103e1565b6001600160a01b03848116600081815260c960209081526040918290205491519185038083529550928616927f6d25be279134f4ecaa4770aff0c3d916d9e7c5ef37b65ed95dbdba411f5d54d5910160405180910390a36107266001600160a01b0385168484611406565b5050600160cc555050565b600054610100900460ff16158080156107515750600054600160ff909116105b8061076b5750303b15801561076b575060005460ff166001145b6107ce5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103e1565b6000805460ff1916600117905580156107f1576000805461ff0019166101001790555b6107fa86611575565b61080384611575565b600085116108235760405162461bcd60e51b81526004016103e1906126ca565b600082116108825760405162461bcd60e51b815260206004820152602660248201527f5269736b2046756e643a204c6f6f7073206c696d69742063616e206e6f74206260448201526565207a65726f60d01b60648201526084016103e1565b61088a61159c565b610893836115cb565b61012f80546001600160a01b038089166001600160a01b03199283161790925561013087905561012d8054928716929091169190911790556108d4826115f2565b801561091a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6109606040518060400160405280602081526020017f736574436f6e7665727469626c6542617365417373657428616464726573732981525061168c565b6001600160a01b0381166109d45760405162461bcd60e51b815260206004820152603560248201527f5269736b2046756e643a206e657720636f6e7665727469626c65206261736520604482015274185cdcd95d081859191c995cdcc81a5b9d985b1a59605a1b60648201526084016103e1565b61012d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f5fa61583da12070720613fefdd68cc6c0e464a71e009742526bd2b2e0ac62cd290600090a35050565b610a2f61145d565b610a3881611575565b61012f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fd37b9d138f53ea58d7e50292588239a46efa8f523966febf4066da96defc77fd90600090a35050565b6000600260cc5403610aaf5760405162461bcd60e51b81526004016103e19061268d565b600260cc81905550610ad8604051806060016040528060388152602001612cc06038913961168c565b42821015610b285760405162461bcd60e51b815260206004820152601a60248201527f5269736b2066756e643a20646561646c696e652070617373656400000000000060448201526064016103e1565b60cb546001600160a01b0316610b3d81611575565b878614610bb25760405162461bcd60e51b815260206004820152603860248201527f5269736b2066756e643a206d61726b65747320616e6420616d6f756e74734f7560448201527f744d696e2061726520756e657175616c206c656e67746873000000000000000060648201526084016103e1565b878414610c1a5760405162461bcd60e51b815260206004820152603060248201527f5269736b2066756e643a206d61726b65747320616e642070617468732061726560448201526f20756e657175616c206c656e6774687360801b60648201526084016103e1565b600088610c2681611726565b60005b81811015610f8c5760008c8c83818110610c4557610c45612712565b9050602002016020810190610c5a91906124d4565b6001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbb9190612728565b604051637aee632d60e01b81526001600160a01b038083166004830152919250600091871690637aee632d90602401600060405180830381865afa158015610d07573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d2f91908101906127f5565b9050816001600160a01b031681604001516001600160a01b031614610da65760405162461bcd60e51b815260206004820152602760248201527f636f6d7074726f6c6c657220646f65736e277420657869737420706f6f6c20726044820152666567697374727960c81b60648201526084016103e1565b816001600160a01b0316633d98a1e58f8f86818110610dc757610dc7612712565b9050602002016020810190610ddc91906124d4565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4491906128eb565b610e875760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d081a5cc81b9bdd081b1a5cdd195960621b60448201526064016103e1565b6000610ef68f8f86818110610e9e57610e9e612712565b9050602002016020810190610eb391906124d4565b848f8f88818110610ec657610ec6612712565b905060200201358e8e89818110610edf57610edf612712565b9050602002810190610ef1919061290d565b611757565b6001600160a01b03808516600090815260ca6020908152604080832061012d54909416835292905290812080549293508392909190610f3690849061296d565b909155505061012d546001600160a01b0316600090815260c9602052604081208054839290610f6690849061296d565b90915550610f769050818761296d565b955050505080610f8590612985565b9050610c29565b507fb17530966b045b50d4975e7f05048ca00d7335780c24f1c465165a4b94b2d37d8b8b8b8b86604051610fc49594939291906129e7565b60405180910390a150600160cc559998505050505050505050565b6000610fea82611575565b826001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104b91906128eb565b6110675760405162461bcd60e51b81526004016103e190612a42565b506001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b61109b61145d565b6110a56000611cfa565b565b6110e56040518060400160405280601e81526020017f7365744d696e416d6f756e74546f436f6e766572742875696e7432353629000081525061168c565b600081116111055760405162461bcd60e51b81526004016103e1906126ca565b61013080549082905560408051828152602081018490527fada67d0d38fa20c8ae6a5c17cb9d60b0fe7f2d4e4f27ac9ee55e54ac88de9d8d91015b60405180910390a15050565b61115461145d565b61115d81611575565b61012e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fb6e5fcf02f7fbb8acfbaa3bac4fd5abf9ff51e3f2e8884b5498927179b211b2890600090a35050565b60655433906001600160a01b0316811461121e5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016103e1565b61059d81611cfa565b61122f61145d565b61123881611575565b60cb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b61129261145d565b61059d816115f2565b6000816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fe91906128eb565b6113595760405162461bcd60e51b815260206004820152602660248201527f5269736b2046756e643a20436f6d7074726f6c6c6572206164647265737320696044820152651b9d985b1a5960d21b60648201526084016103e1565b506001600160a01b03908116600090815260ca6020908152604080832061012d549094168352929052205490565b6113918282611d13565b5050565b61139d61145d565b606580546001600160a01b0383166001600160a01b031990911681179091556113ce6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611458908490612046565b505050565b6033546001600160a01b031633146110a55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103e1565b6001600160a01b03811661151b5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b60648201526084016103e1565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa09101611140565b6001600160a01b03811661059d576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff166115c35760405162461bcd60e51b81526004016103e190612a8d565b6110a561211b565b600054610100900460ff166105945760405162461bcd60e51b81526004016103e190612a8d565b60fb54811161164e5760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b60648201526084016103e1565b60fb80549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa9101611140565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab906116bf9033908690600401612b04565b602060405180830381865afa1580156116dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170091906128eb565b90508061139157333083604051634a3fa29360e01b81526004016103e193929190612b28565b60fb5481111561059d5760fb5460405163792bfb1b60e11b81526004810191909152602481018290526044016103e1565b6000836000036117cf5760405162461bcd60e51b815260206004820152603c60248201527f5269736b46756e643a20616d6f756e744f75744d696e206d757374206265206760448201527f726561746572207468616e203020746f20737761702076546f6b656e0000000060648201526084016103e1565b600080876001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190612728565b61012d546001600160a01b03898116600090815260ca6020908152604080832084871684529091528120549394509116919081900361187a576000945050505050611cf1565b6000896001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190612728565b60405163b62cad6960e01b81526001600160a01b0385811660048301529192509082169063b62cad6990602401600060405180830381600087803b15801561192557600080fd5b505af1158015611939573d6000803e3d6000fd5b50506040805160208101918290526341976e0960e01b9091526001600160a01b03868116602483015260009350909150819084166341976e0960448301602060405180830381865afa158015611993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b791906126b1565b9052905060006119c7828c61214b565b905061013054811015611a2a5760405162461bcd60e51b815260206004820152602560248201527f5269736b46756e643a206d696e416d6f756e74546f436f6e766572742076696f6044820152641b185d195960da1b60648201526084016103e1565b6001600160a01b038616600090815260c9602052604081208054869290611a52908490612b54565b90915550506001600160a01b03808d16600090815260ca60209081526040808320938a1683529290529081208054869290611a8e908490612b54565b90915550506001600160a01b0386811690861614611ce357856001600160a01b03168a8a6000818110611ac357611ac3612712565b9050602002016020810190611ad891906124d4565b6001600160a01b031614611b545760405162461bcd60e51b815260206004820152603860248201527f5269736b46756e643a20737761702070617468206d757374207374617274207760448201527f6974682074686520756e6465726c79696e67206173736574000000000000000060648201526084016103e1565b6001600160a01b0385168a8a611b6b600182612b54565b818110611b7a57611b7a612712565b9050602002016020810190611b8f91906124d4565b6001600160a01b031614611c035760405162461bcd60e51b815260206004820152603560248201527f5269736b46756e643a2066696e616c6c792070617468206d75737420626520636044820152741bdb9d995c9d1a589b194818985cd948185cdcd95d605a1b60648201526084016103e1565b61012f546001600160a01b0390811690611c2190881682600061216b565b611c356001600160a01b038816828761216b565b6000816001600160a01b03166338ed1739878f8f8f30426040518763ffffffff1660e01b8152600401611c6d96959493929190612b6b565b6000604051808303816000875af1158015611c8c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cb49190810190612ba9565b905080611cc260018d612b54565b81518110611cd257611cd2612712565b602002602001015198505050611ce7565b8396505b5094955050505050505b95945050505050565b606580546001600160a01b031916905561059d81612257565b611d1c81611575565b816001600160a01b0316627e3dd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7d91906128eb565b611d995760405162461bcd60e51b81526004016103e190612a42565b60cb546001600160a01b031680611e0b5760405162461bcd60e51b815260206004820152603060248201527f5265736572766548656c706572733a20506f6f6c20526567697374727920616460448201526f191c995cdcc81a5cc81b9bdd081cd95d60821b60648201526084016103e1565b60405163266e0a7f60e01b81526001600160a01b03848116600483015283811660248301526000919083169063266e0a7f90604401602060405180830381865afa158015611e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e819190612728565b6001600160a01b031603611ef25760405162461bcd60e51b815260206004820152603260248201527f5265736572766548656c706572733a2054686520706f6f6c20646f65736e2774604482015271081cdd5c1c1bdc9d081d1a1948185cdcd95d60721b60648201526084016103e1565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5d91906126b1565b6001600160a01b038416600090815260c960205260409020549091508082111561203f576001600160a01b038416600090815260c960205260408120805483850392839291611fad90849061296d565b90915550506001600160a01b03808716600090815260ca6020908152604080832093891683529290529081208054839290611fe990849061296d565b92505081905550846001600160a01b0316866001600160a01b03167fc39e3e80c0219fde334a8cb5d8468b628482e23388b6e809c90cb00c63c8ce388360405161203591815260200190565b60405180910390a3505b5050505050565b600061209b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122a99092919063ffffffff16565b90508051600014806120bc5750808060200190518101906120bc91906128eb565b6114585760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103e1565b600054610100900460ff166121425760405162461bcd60e51b81526004016103e190612a8d565b6110a533611cfa565b60008061215884846122b8565b9050612163816122e9565b949350505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1790529151909160009182918716906121c9908590612c4f565b6000604051808303816000865af19150503d8060008114612206576040519150601f19603f3d011682016040523d82523d6000602084013e61220b565b606091505b5091509150811580612239575080511580159061223957508080602001905181019061223791906128eb565b155b1561091a57604051633e3f8f7360e01b815260040160405180910390fd5b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60606121638484600085612307565b60408051602081019091526000815260405180602001604052806122e08560000151856123e2565b90529392505050565b805160009061230190670de0b6b3a764000090612c6b565b92915050565b6060824710156123685760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103e1565b600080866001600160a01b031685876040516123849190612c4f565b60006040518083038185875af1925050503d80600081146123c1576040519150601f19603f3d011682016040523d82523d6000602084013e6123c6565b606091505b50915091506123d7878383876123f5565b979650505050505050565b60006123ee8284612c8d565b9392505050565b6060831561246457825160000361245d576001600160a01b0385163b61245d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103e1565b5081612163565b61216383838151156124795781518083602001fd5b8060405162461bcd60e51b81526004016103e19190612cac565b6001600160a01b038116811461059d57600080fd5b600080604083850312156124bb57600080fd5b82356124c681612493565b946020939093013593505050565b6000602082840312156124e657600080fd5b81356123ee81612493565b6000806040838503121561250457600080fd5b823561250f81612493565b9150602083013561251f81612493565b809150509250929050565b600080600080600060a0868803121561254257600080fd5b853561254d81612493565b945060208601359350604086013561256481612493565b9250606086013561257481612493565b949793965091946080013592915050565b60008083601f84011261259757600080fd5b50813567ffffffffffffffff8111156125af57600080fd5b6020830191508360208260051b85010111156125ca57600080fd5b9250929050565b60008060008060008060006080888a0312156125ec57600080fd5b873567ffffffffffffffff8082111561260457600080fd5b6126108b838c01612585565b909950975060208a013591508082111561262957600080fd5b6126358b838c01612585565b909750955060408a013591508082111561264e57600080fd5b5061265b8a828b01612585565b989b979a50959894979596606090950135949350505050565b60006020828403121561268657600080fd5b5035919050565b6020808252600a90820152691c994b595b9d195c995960b21b604082015260600190565b6000602082840312156126c357600080fd5b5051919050565b60208082526028908201527f5269736b2046756e643a20496e76616c6964206d696e20616d6f756e7420746f6040820152670818dbdb9d995c9d60c21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561273a57600080fd5b81516123ee81612493565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561277e5761277e612745565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156127ad576127ad612745565b604052919050565b60005b838110156127d05781810151838201526020016127b8565b838111156127df576000848401525b50505050565b80516127f081612493565b919050565b6000602080838503121561280857600080fd5b825167ffffffffffffffff8082111561282057600080fd5b9084019060a0828703121561283457600080fd5b61283c61275b565b82518281111561284b57600080fd5b8301601f8101881361285c57600080fd5b80518381111561286e5761286e612745565b612880601f8201601f19168701612784565b9350808452888682840101111561289657600080fd5b6128a5818786018885016127b5565b50508181526128b58484016127e5565b848201526128c5604084016127e5565b604082015260608301516060820152608083015160808201528094505050505092915050565b6000602082840312156128fd57600080fd5b815180151581146123ee57600080fd5b6000808335601e1984360301811261292457600080fd5b83018035915067ffffffffffffffff82111561293f57600080fd5b6020019150600581901b36038213156125ca57600080fd5b634e487b7160e01b600052601160045260246000fd5b6000821982111561298057612980612957565b500190565b60006001820161299757612997612957565b5060010190565b8183526000602080850194508260005b858110156129dc5781356129c181612493565b6001600160a01b0316875295820195908201906001016129ae565b509495945050505050565b6060815260006129fb60608301878961299e565b82810360208401528481526001600160fb1b03851115612a1a57600080fd5b8460051b80876020840137600091016020019081526040929092019290925295945050505050565b6020808252602b908201527f5265736572766548656c706572733a20436f6d7074726f6c6c6572206164647260408201526a195cdcc81a5b9d985b1a5960aa1b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008151808452612af08160208601602086016127b5565b601f01601f19169290920160200192915050565b6001600160a01b038316815260406020820181905260009061216390830184612ad8565b6001600160a01b03848116825283166020820152606060408201819052600090611cf190830184612ad8565b600082821015612b6657612b66612957565b500390565b86815285602082015260a060408201526000612b8b60a08301868861299e565b6001600160a01b039490941660608301525060800152949350505050565b60006020808385031215612bbc57600080fd5b825167ffffffffffffffff80821115612bd457600080fd5b818501915085601f830112612be857600080fd5b815181811115612bfa57612bfa612745565b8060051b9150612c0b848301612784565b8181529183018401918481019088841115612c2557600080fd5b938501935b83851015612c4357845182529385019390850190612c2a565b98975050505050505050565b60008251612c618184602087016127b5565b9190910192915050565b600082612c8857634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612ca757612ca7612957565b500290565b6020815260006123ee6020830184612ad856fe73776170506f6f6c7341737365747328616464726573735b5d2c75696e743235365b5d2c616464726573735b5d5b5d2c75696e7432353629a26469706673582212200df4784c551e6f296a40813ffbdb6c465608d0b9582f5f659a9257b405a4147e64736f6c634300080d0033", + "devdoc": { + "author": "Venus", + "details": "This contract does not support BNB.", + "kind": "dev", + "methods": { + "acceptOwnership()": { + "details": "The new owner accepts the ownership transfer." + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor", + "details": "Note that the contract is upgradeable. Use initialize() or reinitializers to set the state variables." + }, + "getPoolAssetReserve(address,address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "asset": "Asset address.", + "comptroller": "Comptroller address(pool)." + }, + "returns": { + "_0": "Asset's reserve in risk fund." + } + }, + "getPoolsBaseAssetReserves(address)": { + "params": { + "comptroller": "Comptroller address(pool)." + }, + "returns": { + "_0": "Base Asset's reserve in risk fund." + } + }, + "initialize(address,uint256,address,address,uint256)": { + "custom:error": "ZeroAddressNotAllowed is thrown when PCS router address is zeroZeroAddressNotAllowed is thrown when convertible base asset address is zero", + "params": { + "accessControlManager_": "Address of the access control contract", + "convertibleBaseAsset_": "Address of the base asset", + "loopsLimit_": "Limit for the loops in the contract to avoid DOS", + "minAmountToConvert_": "Minimum amount assets must be worth to convert into base asset", + "pancakeSwapRouter_": "Address of the PancakeSwap router" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pendingOwner()": { + "details": "Returns the address of the pending owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "setAccessControlManager(address)": { + "custom:access": "Only Governance", + "custom:event": "Emits NewAccessControlManager event", + "details": "Admin function to set address of AccessControlManager", + "params": { + "accessControlManager_": "The new address of the AccessControlManager" + } + }, + "setConvertibleBaseAsset(address)": { + "params": { + "_convertibleBaseAsset": "Address for new convertible base asset." + } + }, + "setMaxLoopsLimit(uint256)": { + "params": { + "limit": "Limit for the max loops can execute at a time" + } + }, + "setMinAmountToConvert(uint256)": { + "params": { + "minAmountToConvert_": "Min amount to convert." + } + }, + "setPancakeSwapRouter(address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when PCS router address is zero", + "params": { + "pancakeSwapRouter_": "Address of the PancakeSwap router" + } + }, + "setPoolRegistry(address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when pool registry address is zero", + "params": { + "poolRegistry_": "Address of the pool registry" + } + }, + "setShortfallContractAddress(address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when shortfall contract address is zero", + "params": { + "shortfallContractAddress_": "Address of the auction contract" + } + }, + "swapPoolsAssets(address[],uint256[],address[][],uint256)": { + "custom:error": "ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured", + "params": { + "amountsOutMin": "Minimum amount to receive for swap", + "deadline": "Deadline for the swap", + "markets": "Array of vTokens whose assets to swap for base asset", + "paths": "A path consisting of PCS token pairs for each swap" + }, + "returns": { + "_0": "Number of swapped tokens" + } + }, + "sweepToken(address,address)": { + "custom:access": "Only Owner", + "custom:error": "ZeroAddressNotAllowed is thrown when asset address is zero", + "params": { + "_to": "Recipient of the output tokens.", + "_token": "The address of the BEP-20 token to sweep" + } + }, + "transferOwnership(address)": { + "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." + }, + "transferReserveForAuction(address,uint256)": { + "params": { + "amount": "Amount to be transferred to auction contract.", + "comptroller": "Comptroller of the pool." + }, + "returns": { + "_0": "Number reserved tokens." + } + }, + "updateAssetsState(address,address)": { + "params": { + "asset": "Asset address.", + "comptroller": "Comptroller address(pool)." + } + } + }, + "title": "RiskFund", + "version": 1 + }, + "userdoc": { + "errors": { + "ApproveFailed()": [ + { + "notice": "Thrown if a contract is unable to approve a transfer" + } + ], + "MaxLoopsLimitExceeded(uint256,uint256)": [ + { + "notice": "Thrown an error on maxLoopsLimit exceeds for any loop" + } + ], + "Unauthorized(address,address,string)": [ + { + "notice": "Thrown when the action is prohibited by AccessControlManager" + } + ], + "ZeroAddressNotAllowed()": [ + { + "notice": "Thrown if the supplied address is a zero address where it is not allowed" + } + ] + }, + "events": { + "AssetsReservesUpdated(address,address,uint256)": { + "notice": "Event emitted after the update of the assets reserves." + }, + "ConvertibleBaseAssetUpdated(address,address)": { + "notice": "Emitted when convertible base asset is updated" + }, + "MaxLoopsLimitUpdated(uint256,uint256)": { + "notice": "Emitted when max loops limit is set" + }, + "MinAmountToConvertUpdated(uint256,uint256)": { + "notice": "Emitted when minimum amount to convert is updated" + }, + "NewAccessControlManager(address,address)": { + "notice": "Emitted when access control manager contract address is changed" + }, + "PancakeSwapRouterUpdated(address,address)": { + "notice": "Emitted when PancakeSwap router contract address is updated" + }, + "PoolRegistryUpdated(address,address)": { + "notice": "Emitted when pool registry address is updated" + }, + "ShortfallContractUpdated(address,address)": { + "notice": "Emitted when shortfall contract address is updated" + }, + "SwappedPoolsAssets(address[],uint256[],uint256)": { + "notice": "Emitted when pools assets are swapped" + }, + "SweepToken(address,address,uint256)": { + "notice": "event emitted on sweep token success" + }, + "TransferredReserveForAuction(address,uint256)": { + "notice": "Emitted when reserves are transferred for auction" + } + }, + "kind": "user", + "methods": { + "accessControlManager()": { + "notice": "Returns the address of the access control manager contract" + }, + "getPoolAssetReserve(address,address)": { + "notice": "Get the Amount of the asset in the risk fund for the specific pool." + }, + "getPoolsBaseAssetReserves(address)": { + "notice": "Get the Amount of the Base asset in the risk fund for the specific pool." + }, + "initialize(address,uint256,address,address,uint256)": { + "notice": "Initializes the deployer to owner." + }, + "setAccessControlManager(address)": { + "notice": "Sets the address of AccessControlManager" + }, + "setConvertibleBaseAsset(address)": { + "notice": "Sets a new convertible base asset" + }, + "setMaxLoopsLimit(uint256)": { + "notice": "Set the limit for the loops can iterate to avoid the DOS" + }, + "setMinAmountToConvert(uint256)": { + "notice": "Min amount to convert setter" + }, + "setPancakeSwapRouter(address)": { + "notice": "PancakeSwap router address setter" + }, + "setPoolRegistry(address)": { + "notice": "Pool registry setter" + }, + "setShortfallContractAddress(address)": { + "notice": "Shortfall contract address setter" + }, + "swapPoolsAssets(address[],uint256[],address[][],uint256)": { + "notice": "Swap array of pool assets into base asset's tokens of at least a minimum amount" + }, + "sweepToken(address,address)": { + "notice": "A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input" + }, + "transferReserveForAuction(address,uint256)": { + "notice": "Transfer tokens for auction." + }, + "updateAssetsState(address,address)": { + "notice": "Update the reserve of the asset for the specific pool after transferring to risk fund." + } + }, + "notice": "Contract with basic features to track/hold different assets for different Comptrollers.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 290, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 293, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1397, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 162, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 282, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 71, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_pendingOwner", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 150, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 3341, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_accessControlManager", + "offset": 0, + "slot": "151", + "type": "t_contract(IAccessControlManagerV8)3525" + }, + { + "astId": 3346, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 13338, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "assetsReserves", + "offset": 0, + "slot": "201", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 13344, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "_poolsAssetsReserves", + "offset": 0, + "slot": "202", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 13346, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "poolRegistry", + "offset": 0, + "slot": "203", + "type": "t_address" + }, + { + "astId": 13349, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "status", + "offset": 0, + "slot": "204", + "type": "t_uint256" + }, + { + "astId": 13354, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "205", + "type": "t_array(t_uint256)46_storage" + }, + { + "astId": 10571, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "maxLoopsLimit", + "offset": 0, + "slot": "251", + "type": "t_uint256" + }, + { + "astId": 10576, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 13647, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "convertibleBaseAsset", + "offset": 0, + "slot": "301", + "type": "t_address" + }, + { + "astId": 13649, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "shortfall", + "offset": 0, + "slot": "302", + "type": "t_address" + }, + { + "astId": 13651, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "pancakeSwapRouter", + "offset": 0, + "slot": "303", + "type": "t_address" + }, + { + "astId": 13653, + "contract": "contracts/RiskFund/RiskFund.sol:RiskFund", + "label": "minAmountToConvert", + "offset": 0, + "slot": "304", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)46_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[46]", + "numberOfBytes": "1472" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IAccessControlManagerV8)3525": { + "encoding": "inplace", + "label": "contract IAccessControlManagerV8", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} diff --git a/deployments/bsctestnet/RiskFund_Proxy.json b/deployments/bsctestnet/RiskFund_Proxy.json new file mode 100644 index 000000000..fc6896c91 --- /dev/null +++ b/deployments/bsctestnet/RiskFund_Proxy.json @@ -0,0 +1,277 @@ +{ + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "transactionIndex": 2, + "gasUsed": "888546", + "logsBloom": "0x1000000000000000000000000000000040000000000000000080000800000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000000000000000000000000000000000000000081000000000000800000000000000000800000002000008400000000000000800000000000000000002000000020000000000000000001040000000000004400000000000000000020000000000200000000000000002000000000000800000000000000000000000000", + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e", + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000665085ecc7bc1b59c9872d030f2bd6c724739709" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", + "logIndex": 3, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": ["0xc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064", + "logIndex": 4, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 5, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + }, + { + "transactionIndex": 2, + "blockNumber": 33267915, + "transactionHash": "0x137af09eb8dd07c3fdb64fc7dac3bf47ee320af3b8597d9f14b55763354fb075", + "address": "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007877ffd62649b6a1557b55d4c20fcbab17344c91", + "logIndex": 6, + "blockHash": "0x5a25a1167f00e0ed468211a97c958ad55c7aeccf6fa0ec154c4d85bb4f655f3e" + } + ], + "blockNumber": 33267915, + "cumulativeGasUsed": "1000882", + "status": 1, + "byzantium": true + }, + "args": [ + "0x665085EcC7bc1B59c9872d030f2Bd6c724739709", + "0x7877fFd62649b6A1557B55D4c20fcBaB17344C91", + "0x2a1d054700000000000000000000000083edf1dee1b730b7e8e13c00ba76027d63a51ac00000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000a11c8d9dc9b66e209ef60f0c8d969d3cd988782c00000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa0000000000000000000000000000000000000000000000000000000000000064" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsctestnet/Shortfall.json b/deployments/bsctestnet/Shortfall.json new file mode 100644 index 000000000..b903a8250 --- /dev/null +++ b/deployments/bsctestnet/Shortfall.json @@ -0,0 +1,1192 @@ +{ + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableBalance", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "owedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientDebt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFind", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketDebt", + "type": "uint256[]" + } + ], + "name": "AuctionClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "AuctionRestarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketsDebt", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "name": "AuctionStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "bidder", + "type": "address" + } + ], + "name": "BidPlaced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldIncentiveBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newIncentiveBps", + "type": "uint256" + } + ], + "name": "IncentiveBpsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinimumPoolBadDebt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "MinimumPoolBadDebtUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldNextBidderBlockLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newNextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "NextBidderBlockLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldWaitForFirstBidder", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWaitForFirstBidder", + "type": "uint256" + } + ], + "name": "WaitForFirstBidderUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "auctions", + "outputs": [ + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "internalType": "enum Shortfall.AuctionStatus", + "name": "status", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "highestBidBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "claimTokenDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "closeAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "incentiveBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IRiskFund", + "name": "riskFund_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minimumPoolBadDebt_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minimumPoolBadDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextBidderBlockLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "placeBid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "restartAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resumeAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "contract IRiskFund", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "startAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalTokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_incentiveBps", + "type": "uint256" + } + ], + "name": "updateIncentiveBps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "updateMinimumPoolBadDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "updateNextBidderBlockLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "updatePoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_waitForFirstBidder", + "type": "uint256" + } + ], + "name": "updateWaitForFirstBidder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "waitForFirstBidder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "transactionIndex": 2, + "gasUsed": "933014", + "logsBloom": "0x1000000000000000000000000000000040000000000000000080000800000000000000400000000000000000000000000000000000000000400000000000c000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000040000000000000000000000000000000000080000000000000800000000000000000000000000000000400200000000000800000000000000000000000000020000000000000000000040000000000000400000000000000000020000020000000000000000000000000000000004800000000000000000000000000", + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af", + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000040ec22d1aa01236de2fb3df049de9f104a25c87c" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + }, + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + }, + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", + "logIndex": 2, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + }, + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 3, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + }, + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007877ffd62649b6a1557b55d4c20fcbab17344c91", + "logIndex": 4, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + } + ], + "blockNumber": 33267929, + "cumulativeGasUsed": "1009663", + "status": 1, + "byzantium": true + }, + "args": [ + "0x40Ec22d1aA01236dE2FB3dF049DE9f104A25c87C", + "0x7877fFd62649b6A1557B55D4c20fcBaB17344C91", + "0xc350a1b5000000000000000000000000487cef72dacabd7e12e633bb3b63815a386f701200000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0x487CeF72dacABD7E12e633bb3B63815a386f7012", + "1000000000000000000000", + "0x45f8a08F534f34A97187626E05d4b6648Eeaa9AA" + ] + }, + "implementation": "0x40Ec22d1aA01236dE2FB3dF049DE9f104A25c87C", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsctestnet/Shortfall_Implementation.json b/deployments/bsctestnet/Shortfall_Implementation.json new file mode 100644 index 000000000..061d6cdcb --- /dev/null +++ b/deployments/bsctestnet/Shortfall_Implementation.json @@ -0,0 +1,1641 @@ +{ + "address": "0x40Ec22d1aA01236dE2FB3dF049DE9f104A25c87C", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableBalance", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "owedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientDebt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFind", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketDebt", + "type": "uint256[]" + } + ], + "name": "AuctionClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "AuctionRestarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "markets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "marketsDebt", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "name": "AuctionStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "AuctionsResumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "bidder", + "type": "address" + } + ], + "name": "BidPlaced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldIncentiveBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newIncentiveBps", + "type": "uint256" + } + ], + "name": "IncentiveBpsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMinimumPoolBadDebt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "MinimumPoolBadDebtUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldNextBidderBlockLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newNextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "NextBidderBlockLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPoolRegistry", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPoolRegistry", + "type": "address" + } + ], + "name": "PoolRegistryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDebtClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldWaitForFirstBidder", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWaitForFirstBidder", + "type": "uint256" + } + ], + "name": "WaitForFirstBidderUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "auctions", + "outputs": [ + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "enum Shortfall.AuctionType", + "name": "auctionType", + "type": "uint8" + }, + { + "internalType": "enum Shortfall.AuctionStatus", + "name": "status", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "seizedRiskFund", + "type": "uint256" + }, + { + "internalType": "address", + "name": "highestBidder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "highestBidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "highestBidBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBidBps", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "claimTokenDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "closeAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "incentiveBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IRiskFund", + "name": "riskFund_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minimumPoolBadDebt_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minimumPoolBadDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextBidderBlockLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "bidBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "auctionStartBlock", + "type": "uint256" + } + ], + "name": "placeBid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "restartAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resumeAuctions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFund", + "outputs": [ + { + "internalType": "contract IRiskFund", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "startAuction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalTokenDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_incentiveBps", + "type": "uint256" + } + ], + "name": "updateIncentiveBps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minimumPoolBadDebt", + "type": "uint256" + } + ], + "name": "updateMinimumPoolBadDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nextBidderBlockLimit", + "type": "uint256" + } + ], + "name": "updateNextBidderBlockLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolRegistry_", + "type": "address" + } + ], + "name": "updatePoolRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_waitForFirstBidder", + "type": "uint256" + } + ], + "name": "updateWaitForFirstBidder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "waitForFirstBidder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x84c0af92ef37e455bee7619fb44cf8b07c1b8ceb3816b73bdcebc2a9b07e9cb4", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0x40Ec22d1aA01236dE2FB3dF049DE9f104A25c87C", + "transactionIndex": 2, + "gasUsed": "3151308", + "logsBloom": "0x00000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd252812dceab58d0c7ef832abe34ee2e595fa9c5e9c3eb519253819ad7595afc", + "transactionHash": "0x84c0af92ef37e455bee7619fb44cf8b07c1b8ceb3816b73bdcebc2a9b07e9cb4", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 33267922, + "transactionHash": "0x84c0af92ef37e455bee7619fb44cf8b07c1b8ceb3816b73bdcebc2a9b07e9cb4", + "address": "0x40Ec22d1aA01236dE2FB3dF049DE9f104A25c87C", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 1, + "blockHash": "0xd252812dceab58d0c7ef832abe34ee2e595fa9c5e9c3eb519253819ad7595afc" + } + ], + "blockNumber": 33267922, + "cumulativeGasUsed": "3263644", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "394b060e0e484d4aa39aea929deecf07", + "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableBalance\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"owedAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"InsufficientDebt\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"calledContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"methodSignature\",\"type\":\"string\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"highestBidder\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"highestBidBps\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"seizedRiskFind\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"contract VToken[]\",\"name\":\"markets\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"marketDebt\",\"type\":\"uint256[]\"}],\"name\":\"AuctionClosed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"}],\"name\":\"AuctionRestarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"enum Shortfall.AuctionType\",\"name\":\"auctionType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"contract VToken[]\",\"name\":\"markets\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"marketsDebt\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"seizedRiskFund\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startBidBps\",\"type\":\"uint256\"}],\"name\":\"AuctionStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AuctionsPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AuctionsResumed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"bidBps\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bidder\",\"type\":\"address\"}],\"name\":\"BidPlaced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldIncentiveBps\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newIncentiveBps\",\"type\":\"uint256\"}],\"name\":\"IncentiveBpsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMinimumPoolBadDebt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMinimumPoolBadDebt\",\"type\":\"uint256\"}],\"name\":\"MinimumPoolBadDebtUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNextBidderBlockLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNextBidderBlockLimit\",\"type\":\"uint256\"}],\"name\":\"NextBidderBlockLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPoolRegistry\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPoolRegistry\",\"type\":\"address\"}],\"name\":\"PoolRegistryUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenDebtAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenDebtClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldWaitForFirstBidder\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newWaitForFirstBidder\",\"type\":\"uint256\"}],\"name\":\"WaitForFirstBidderUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"auctions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"startBlock\",\"type\":\"uint256\"},{\"internalType\":\"enum Shortfall.AuctionType\",\"name\":\"auctionType\",\"type\":\"uint8\"},{\"internalType\":\"enum Shortfall.AuctionStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"seizedRiskFund\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"highestBidder\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"highestBidBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"highestBidBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startBidBps\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"auctionsPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"claimTokenDebt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"}],\"name\":\"closeAuction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"incentiveBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IRiskFund\",\"name\":\"riskFund_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minimumPoolBadDebt_\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minimumPoolBadDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextBidderBlockLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pauseAuctions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"bidBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"auctionStartBlock\",\"type\":\"uint256\"}],\"name\":\"placeBid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"}],\"name\":\"restartAuction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resumeAuctions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"riskFund\",\"outputs\":[{\"internalType\":\"contract IRiskFund\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"comptroller\",\"type\":\"address\"}],\"name\":\"startAuction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"tokenDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalTokenDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_incentiveBps\",\"type\":\"uint256\"}],\"name\":\"updateIncentiveBps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minimumPoolBadDebt\",\"type\":\"uint256\"}],\"name\":\"updateMinimumPoolBadDebt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_nextBidderBlockLimit\",\"type\":\"uint256\"}],\"name\":\"updateNextBidderBlockLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"poolRegistry_\",\"type\":\"address\"}],\"name\":\"updatePoolRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_waitForFirstBidder\",\"type\":\"uint256\"}],\"name\":\"updateWaitForFirstBidder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"waitForFirstBidder\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"errors\":{\"InsufficientBalance(address,address,uint256,uint256)\":[{\"params\":{\"amount\":\"The amount of tokens the contract is trying to transfer\",\"availableBalance\":\"The amount of tokens the contract currently has\",\"recipient\":\"The recipient of the transfer\",\"token\":\"The token the contract is trying to transfer\"}}],\"InsufficientDebt(address,address,uint256,uint256)\":[{\"params\":{\"amount\":\"The amount of tokens the user is trying to claim\",\"owedAmount\":\"The amount of tokens the contract owes to the user\",\"token\":\"The token the user is trying to claim\"}}]},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"claimTokenDebt(address,uint256)\":{\"custom:error\":\"InsufficientDebt The contract doesn't have enough debt to the user\",\"params\":{\"amount_\":\"The amount of tokens to claim (or max uint256 to claim all)\",\"token\":\"The token to claim\"}},\"closeAuction(address)\":{\"custom:event\":\"Emits AuctionClosed event on successful close\",\"params\":{\"comptroller\":\"Comptroller address of the pool\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"initialize(address,uint256,address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when convertible base asset address is zeroZeroAddressNotAllowed is thrown when risk fund address is zero\",\"params\":{\"accessControlManager_\":\"AccessControlManager contract address\",\"minimumPoolBadDebt_\":\"Minimum bad debt in base asset for a pool to start auction\",\"riskFund_\":\"RiskFund contract address\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pauseAuctions()\":{\"custom:access\":\"Restricted by ACM\",\"custom:error\":\"Errors is auctions are paused\",\"custom:event\":\"Emits AuctionsPaused on success\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"placeBid(address,uint256,uint256)\":{\"custom:event\":\"Emits BidPlaced event on success\",\"params\":{\"auctionStartBlock\":\"The block number when auction started\",\"bidBps\":\"The bid percent of the risk fund or bad debt depending on auction type\",\"comptroller\":\"Comptroller address of the pool\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"restartAuction(address)\":{\"custom:event\":\"Emits AuctionRestarted event on successful restart\",\"params\":{\"comptroller\":\"Address of the pool\"}},\"resumeAuctions()\":{\"custom:access\":\"Restricted by ACM\",\"custom:error\":\"Errors is auctions are active\",\"custom:event\":\"Emits AuctionsResumed on success\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewAccessControlManager event\",\"details\":\"Admin function to set address of AccessControlManager\",\"params\":{\"accessControlManager_\":\"The new address of the AccessControlManager\"}},\"startAuction(address)\":{\"custom:event\":\"Emits AuctionStarted event on successErrors if auctions are paused\",\"params\":{\"comptroller\":\"Comptroller address of the pool\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"updateIncentiveBps(uint256)\":{\"custom:access\":\"Restricted by ACM\",\"custom:event\":\"Emits IncentiveBpsUpdated on success\",\"params\":{\"_incentiveBps\":\"New incentive BPS\"}},\"updateMinimumPoolBadDebt(uint256)\":{\"custom:access\":\"Restricted by ACM\",\"custom:event\":\"Emits MinimumPoolBadDebtUpdated on success\",\"params\":{\"_minimumPoolBadDebt\":\"Minimum bad debt in BUSD for a pool to start auction\"}},\"updateNextBidderBlockLimit(uint256)\":{\"custom:access\":\"Restricted by ACM\",\"custom:event\":\"Emits NextBidderBlockLimitUpdated on success\",\"params\":{\"_nextBidderBlockLimit\":\"New next bidder block limit\"}},\"updatePoolRegistry(address)\":{\"custom:access\":\"Restricted to owner\",\"custom:error\":\"ZeroAddressNotAllowed is thrown when pool registry address is zero\",\"custom:event\":\"Emits PoolRegistryUpdated on success\",\"details\":\"After Pool Registry is deployed we need to set the pool registry address\",\"params\":{\"poolRegistry_\":\"Address of pool registry contract\"}},\"updateWaitForFirstBidder(uint256)\":{\"custom:access\":\"Restricted by ACM\",\"custom:event\":\"Emits WaitForFirstBidderUpdated on success\",\"params\":{\"_waitForFirstBidder\":\"New wait for first bidder block count\"}}},\"stateVariables\":{\"MAX_BPS\":{\"details\":\"Max basis points i.e., 100%\"}},\"title\":\"Shortfall\",\"version\":1},\"userdoc\":{\"errors\":{\"InsufficientBalance(address,address,uint256,uint256)\":[{\"notice\":\"Thrown if trying to transfer more tokens than the contract currently has\"}],\"InsufficientDebt(address,address,uint256,uint256)\":[{\"notice\":\"Thrown if the user tries to claim more tokens than they are owed\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"Thrown when the action is prohibited by AccessControlManager\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"AuctionClosed(address,uint256,address,uint256,uint256,address[],uint256[])\":{\"notice\":\"Emitted when a auction is completed\"},\"AuctionRestarted(address,uint256)\":{\"notice\":\"Emitted when a auction is restarted\"},\"AuctionStarted(address,uint256,uint8,address[],uint256[],uint256,uint256)\":{\"notice\":\"Emitted when a auction starts\"},\"AuctionsPaused(address)\":{\"notice\":\"Emitted when auctions are paused\"},\"AuctionsResumed(address)\":{\"notice\":\"Emitted when auctions are unpaused\"},\"BidPlaced(address,uint256,uint256,address)\":{\"notice\":\"Emitted when a bid is placed\"},\"IncentiveBpsUpdated(uint256,uint256)\":{\"notice\":\"Emitted when incentiveBps is updated\"},\"MinimumPoolBadDebtUpdated(uint256,uint256)\":{\"notice\":\"Emitted when minimum pool bad debt is updated\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when access control manager contract address is changed\"},\"NextBidderBlockLimitUpdated(uint256,uint256)\":{\"notice\":\"Emitted when next bidder block limit is updated\"},\"PoolRegistryUpdated(address,address)\":{\"notice\":\"Emitted when pool registry address is updated\"},\"TokenDebtAdded(address,address,uint256)\":{\"notice\":\"Emitted when the contract's debt to the user is increased due to a failed transfer\"},\"TokenDebtClaimed(address,address,uint256)\":{\"notice\":\"Emitted when a user claims tokens that the contract owes them\"},\"WaitForFirstBidderUpdated(uint256,uint256)\":{\"notice\":\"Emitted when wait for first bidder block count is updated\"}},\"kind\":\"user\",\"methods\":{\"accessControlManager()\":{\"notice\":\"Returns the address of the access control manager contract\"},\"auctions(address)\":{\"notice\":\"Auctions for each pool\"},\"auctionsPaused()\":{\"notice\":\"Boolean of if auctions are paused\"},\"claimTokenDebt(address,uint256)\":{\"notice\":\"Transfers the tokens we owe to msg.sender, if any\"},\"closeAuction(address)\":{\"notice\":\"Close an auction\"},\"incentiveBps()\":{\"notice\":\"Incentive to auction participants, initial value set to 1000 or 10%\"},\"initialize(address,uint256,address)\":{\"notice\":\"Initialize the shortfall contract\"},\"minimumPoolBadDebt()\":{\"notice\":\"Minimum USD debt in pool for shortfall to trigger\"},\"nextBidderBlockLimit()\":{\"notice\":\"Time to wait for next bidder. Initially waits for 100 blocks\"},\"pauseAuctions()\":{\"notice\":\"Pause auctions. This disables starting new auctions but lets the current auction finishes\"},\"placeBid(address,uint256,uint256)\":{\"notice\":\"Place a bid greater than the previous in an ongoing auction\"},\"poolRegistry()\":{\"notice\":\"Pool registry address\"},\"restartAuction(address)\":{\"notice\":\"Restart an auction\"},\"resumeAuctions()\":{\"notice\":\"Resume paused auctions.\"},\"riskFund()\":{\"notice\":\"Risk fund address\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of AccessControlManager\"},\"startAuction(address)\":{\"notice\":\"Start a auction when there is not currently one active\"},\"tokenDebt(address,address)\":{\"notice\":\"Mapping (IERC20Upgradeable token => (address user => uint256 amount)). Tracks failed transfers: when a token transfer fails, we record the amount of the transfer, so that the user can redeem this debt later.\"},\"totalTokenDebt(address)\":{\"notice\":\"Mapping (IERC20Upgradeable token => uint256 amount) shows how many tokens the contract owes to all users. This is useful for accounting to understand how much of balanceOf(address(this)) is already owed to users.\"},\"updateIncentiveBps(uint256)\":{\"notice\":\"Updates the incentive BPS\"},\"updateMinimumPoolBadDebt(uint256)\":{\"notice\":\"Update minimum pool bad debt to start auction\"},\"updateNextBidderBlockLimit(uint256)\":{\"notice\":\"Update next bidder block limit which is used determine when an auction can be closed\"},\"updatePoolRegistry(address)\":{\"notice\":\"Update the pool registry this shortfall supports\"},\"updateWaitForFirstBidder(uint256)\":{\"notice\":\"Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted\"},\"waitForFirstBidder()\":{\"notice\":\"Time to wait for first bidder. Initially waits for 100 blocks\"}},\"notice\":\"Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset` is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value. This value is set and can be changed by the authorized accounts. If the pool\\u2019s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise, if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the risk fund in exchange for paying off all the pool's bad debt.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Shortfall/Shortfall.sol\":\"Shortfall\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides 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} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\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\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.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 */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(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 virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\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\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\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\",\"keccak256\":\"0xb82ef33f43b6b96109687d91b39c94573fdccaaa423fe28e8ba0977b31c023e0\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\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 /**\\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 `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable 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 require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\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. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\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 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 */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\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 * _Available since v3.1._\\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\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title Venus Access Control Contract.\\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\\n * The contract allows the owner to set an AccessControlManager contract address.\\n * It can restrict method calls based on the sender's role and the method's signature.\\n */\\n\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n /// @notice Access control manager contract\\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\\n error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Sets the address of AccessControlManager\\n * @dev Admin function to set address of AccessControlManager\\n * @param accessControlManager_ The new address of the AccessControlManager\\n * @custom:event Emits NewAccessControlManager event\\n * @custom:access Only Governance\\n */\\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n _setAccessControlManager(accessControlManager_);\\n }\\n\\n /**\\n * @notice Returns the address of the access control manager contract\\n */\\n function accessControlManager() external view returns (IAccessControlManagerV8) {\\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x618d942756b93e02340a42f3c80aa99fc56be1a96861f5464dc23a76bf30b3a5\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\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\":\"0x41deef84d1839590b243b66506691fde2fb938da01eabde53e82d3b8316fdaf9\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\ninterface OracleInterface {\\n function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n function updatePrice(address vToken) external;\\n\\n function updateAssetPrice(address asset) external;\\n\\n function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n function validatePriceWithAnchorPrice(\\n address asset,\\n uint256 reporterPrice,\\n uint256 anchorPrice\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x40031b19684ca0c912e794d08c2c0b0d8be77d3c1bdc937830a0658eff899650\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n ComptrollerStorage,\\n ComptrollerInterface,\\n ExponentialNoError,\\n MaxLoopsLimitHelper\\n{\\n // PoolRegistry, immutable to save on gas\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address public immutable poolRegistry;\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n /// @notice Emitted when liquidation threshold is changed by admin\\n event NewLiquidationThreshold(\\n VToken vToken,\\n uint256 oldLiquidationThresholdMantissa,\\n uint256 newLiquidationThresholdMantissa\\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\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 the collateral threshold (in USD) for non-batch liquidations is changed\\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\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 a rewards distributor is added\\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n /// @notice Emitted when a market is supported\\n event MarketSupported(VToken vToken);\\n\\n /// @notice Thrown when collateral factor exceeds the upper bound\\n error InvalidCollateralFactor();\\n\\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n error InvalidLiquidationThreshold();\\n\\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n error UnexpectedSender(address expectedSender, address actualSender);\\n\\n /// @notice Thrown when the oracle returns an invalid price for some asset\\n error PriceError(address vToken);\\n\\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n error SnapshotError(address vToken, address user);\\n\\n /// @notice Thrown when the market is not listed\\n error MarketNotListed(address market);\\n\\n /// @notice Thrown when a market has an unexpected comptroller\\n error ComptrollerMismatch();\\n\\n /// @notice Thrown when user is not member of market\\n error MarketNotCollateral(address vToken, address user);\\n\\n /**\\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n * or healAccount) are available.\\n */\\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n error InsufficientLiquidity();\\n\\n /// @notice Thrown when trying to liquidate a healthy account\\n error InsufficientShortfall();\\n\\n /// @notice Thrown when trying to repay more than allowed by close factor\\n error TooMuchRepay();\\n\\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n error NonzeroBorrowBalance();\\n\\n /// @notice Thrown when trying to perform an action that is paused\\n error ActionPaused(address market, Action action);\\n\\n /// @notice Thrown when trying to add a market that is already listed\\n error MarketAlreadyListed(address market);\\n\\n /// @notice Thrown if the supply cap is exceeded\\n error SupplyCapExceeded(address market, uint256 cap);\\n\\n /// @notice Thrown if the borrow cap is exceeded\\n error BorrowCapExceeded(address market, uint256 cap);\\n\\n /// @param poolRegistry_ Pool registry address\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n constructor(address poolRegistry_) {\\n ensureNonzeroAddress(poolRegistry_);\\n\\n poolRegistry = poolRegistry_;\\n _disableInitializers();\\n }\\n\\n /**\\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n * @param accessControlManager Access control manager contract address\\n */\\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager);\\n\\n _setMaxLoopsLimit(loopLimit);\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketEntered is emitted for each market on success\\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n * @custom:access Not restricted\\n */\\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n VToken vToken = VToken(vTokens[i]);\\n\\n _addToMarket(vToken, msg.sender);\\n results[i] = NO_ERROR;\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event MarketExited is emitted on success\\n * @custom:error ActionPaused error is thrown if exiting the market is paused\\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function exitMarket(address vTokenAddress) external override returns (uint256) {\\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n revert NonzeroBorrowBalance();\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\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 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 // load into memory for faster iteration\\n VToken[] memory userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n\\n uint256 assetIndex = len;\\n for (uint256 i; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n assetIndex = i;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(assetIndex < len);\\n\\n // copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage storedList = accountAssets[msg.sender];\\n storedList[assetIndex] = storedList[storedList.length - 1];\\n storedList.pop();\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return NO_ERROR;\\n }\\n\\n /*** Policy Hooks ***/\\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n * @custom:access Not restricted\\n */\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.MINT);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (supplyCap != type(uint256).max) {\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n if (nextTotalSupply > supplyCap) {\\n revert SupplyCapExceeded(vToken, supplyCap);\\n }\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external override {\\n _checkActionPauseState(vToken, Action.REDEEM);\\n\\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n */\\n /// disable-eslint\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external override {\\n _checkActionPauseState(vToken, Action.BORROW);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n _checkSenderIs(vToken);\\n\\n // attempt to add borrower to the market or revert\\n _addToMarket(VToken(msg.sender), borrower);\\n }\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (oracle.getUnderlyingPrice(vToken) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Skipping the cap check for uncapped coins to save some gas\\n if (borrowCap != type(uint256).max) {\\n uint256 totalBorrows = VToken(vToken).totalBorrows();\\n uint256 badDebt = VToken(vToken).badDebt();\\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n if (nextTotalBorrows > borrowCap) {\\n revert BorrowCapExceeded(vToken, borrowCap);\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The account which would borrowed the asset\\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:access Not restricted\\n */\\n function preRepayHook(address vToken, address borrower) external override {\\n _checkActionPauseState(vToken, Action.REPAY);\\n\\n oracle.updatePrice(vToken);\\n\\n if (!markets[vToken].isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\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 borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n */\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external override {\\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n // If we want to pause liquidating to vTokenCollateral, we should pause\\n // Action.SEIZE on it\\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n // Update the prices of tokens\\n updatePrices(borrower);\\n\\n if (!markets[vTokenBorrowed].isListed) {\\n revert MarketNotListed(address(vTokenBorrowed));\\n }\\n if (!markets[vTokenCollateral].isListed) {\\n revert MarketNotListed(address(vTokenCollateral));\\n }\\n\\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\\n if (repayAmount > borrowBalance) {\\n revert TooMuchRepay();\\n }\\n return;\\n }\\n\\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n /* The liquidator should use either liquidateAccount or healAccount */\\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n /* The liquidator may not repay more than what is allowed by the closeFactor */\\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n if (repayAmount > maxClose) {\\n revert TooMuchRepay();\\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n * @custom:access Not restricted\\n */\\n function preSeizeHook(\\n address vTokenCollateral,\\n address seizerContract,\\n address liquidator,\\n address borrower\\n ) external override {\\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n // If we want to pause liquidating vTokenBorrowed, we should pause\\n // Action.LIQUIDATE on it\\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(vTokenCollateral);\\n }\\n\\n if (seizerContract == address(this)) {\\n // If Comptroller is the seizer, just check if collateral's comptroller\\n // is equal to the current address\\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n revert ComptrollerMismatch();\\n }\\n } else {\\n // If the seizer is not the Comptroller, check that the seizer is a\\n // listed market, and that the markets' comptrollers match\\n if (!markets[seizerContract].isListed) {\\n revert MarketNotListed(seizerContract);\\n }\\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n revert ComptrollerMismatch();\\n }\\n }\\n\\n if (!market.accountMembership[borrower]) {\\n revert MarketNotCollateral(vTokenCollateral, borrower);\\n }\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external override {\\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 _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n // Keep the flywheel moving\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n }\\n }\\n\\n /*** Pool-level operations ***/\\n\\n /**\\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n * borrows, and treats the rest of the debt as bad debt (for each market).\\n * The sender has to repay a certain percentage of the debt, computed as\\n * collateral / (borrows * liquidationIncentive).\\n * @param user account to heal\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function healAccount(address user) external {\\n VToken[] memory userAssets = accountAssets[user];\\n uint256 userAssetsCount = userAssets.length;\\n\\n address liquidator = msg.sender;\\n {\\n ResilientOracleInterface oracle_ = oracle;\\n // We need all user's markets to be fresh for the computations to be correct\\n for (uint256 i; i < userAssetsCount; ++i) {\\n userAssets[i].accrueInterest();\\n oracle_.updatePrice(address(userAssets[i]));\\n }\\n }\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n // percentage = collateral / (borrows * liquidation incentive)\\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n Exp memory scaledBorrows = mul_(\\n Exp({ mantissa: snapshot.borrows }),\\n Exp({ mantissa: liquidationIncentiveMantissa })\\n );\\n\\n Exp memory percentage = div_(collateral, scaledBorrows);\\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n }\\n\\n for (uint256 i; i < userAssetsCount; ++i) {\\n VToken market = userAssets[i];\\n\\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n // Seize the entire collateral\\n if (tokens != 0) {\\n market.seize(liquidator, user, tokens);\\n }\\n // Repay a certain percentage of the borrow, forgive the rest\\n if (borrowBalance != 0) {\\n market.healBorrow(liquidator, user, repaymentAmount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n * below the threshold, and the account is insolvent, use healAccount.\\n * @param borrower the borrower address\\n * @param orders an array of liquidation orders\\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n * @custom:access Not restricted\\n */\\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n // We will accrue interest and update the oracle prices later during the liquidation\\n\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n // You should use the regular vToken.liquidateBorrow(...) call\\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n }\\n\\n uint256 collateralToSeize = mul_ScalarTruncate(\\n Exp({ mantissa: liquidationIncentiveMantissa }),\\n snapshot.borrows\\n );\\n if (collateralToSeize >= snapshot.totalCollateral) {\\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n // and record bad debt.\\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n }\\n\\n if (snapshot.shortfall == 0) {\\n revert InsufficientShortfall();\\n }\\n\\n uint256 ordersCount = orders.length;\\n\\n _ensureMaxLoops(ordersCount / 2);\\n\\n for (uint256 i; i < ordersCount; ++i) {\\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n }\\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n revert MarketNotListed(address(orders[i].vTokenCollateral));\\n }\\n\\n LiquidationOrder calldata order = orders[i];\\n order.vTokenBorrowed.forceLiquidateBorrow(\\n msg.sender,\\n borrower,\\n order.repayAmount,\\n order.vTokenCollateral,\\n true\\n );\\n }\\n\\n VToken[] memory borrowMarkets = accountAssets[borrower];\\n uint256 marketsCount = borrowMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n }\\n }\\n\\n /**\\n * @notice Sets the closeFactor to use when liquidating borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @custom:event Emits NewCloseFactor on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev This function is restricted by the AccessControlManager\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n * and NewLiquidationThreshold when liquidation threshold is updated\\n * @custom:error MarketNotListed error is thrown when the market is not listed\\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa,\\n uint256 newLiquidationThresholdMantissa\\n ) external {\\n _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n // Check collateral factor <= 0.9\\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n revert InvalidCollateralFactor();\\n }\\n\\n // Ensure that liquidation threshold <= 1\\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // Ensure that liquidation threshold >= CF\\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n revert InvalidLiquidationThreshold();\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n revert PriceError(address(vToken));\\n }\\n\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n }\\n\\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n }\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev This function is restricted by the AccessControlManager\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @custom:event Emits NewLiquidationIncentive on success\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\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\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Only callable by the PoolRegistry\\n * @param vToken The address of the market (token) to list\\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n * @custom:access Only PoolRegistry\\n */\\n function supportMarket(VToken vToken) external {\\n _checkSenderIs(poolRegistry);\\n\\n if (markets[address(vToken)].isListed) {\\n revert MarketAlreadyListed(address(vToken));\\n }\\n\\n require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.collateralFactorMantissa = 0;\\n newMarket.liquidationThresholdMantissa = 0;\\n\\n _addMarket(address(vToken));\\n\\n uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n for (uint256 i; i < rewardDistributorsCount; ++i) {\\n rewardsDistributors[i].initializeMarket(address(vToken));\\n }\\n\\n emit MarketSupported(vToken);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n until the total borrows amount goes below the new borrow cap\\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 type(uint256).max corresponds to unlimited borrowing.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n _checkAccessAllowed(\\\"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 _ensureMaxLoops(numMarkets);\\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 markets. Supply that brings total Supply to or above supply cap will revert.\\n * @dev This function is restricted by the AccessControlManager\\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n until the total supplies amount goes below the new supply cap\\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 type(uint256).max corresponds to unlimited supply.\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n uint256 vTokensCount = vTokens.length;\\n\\n require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Pause/unpause specified actions\\n * @dev This function is restricted by the AccessControlManager\\n * @param marketsList Markets to pause/unpause the actions on\\n * @param actionsList List of action ids to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setActionsPaused(\\n VToken[] calldata marketsList,\\n Action[] calldata actionsList,\\n bool paused\\n ) external {\\n _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n uint256 marketsCount = marketsList.length;\\n uint256 actionsCount = actionsList.length;\\n\\n _ensureMaxLoops(marketsCount * actionsCount);\\n\\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n }\\n }\\n }\\n\\n /**\\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n * operations like liquidateAccount or healAccount.\\n * @dev This function is restricted by the AccessControlManager\\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n minLiquidatableCollateral = newMinLiquidatableCollateral;\\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n }\\n\\n /**\\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\\n * @dev Only callable by the admin\\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n * @custom:access Only Governance\\n * @custom:event Emits NewRewardsDistributor with distributor address\\n */\\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n rewardsDistributors.push(_rewardsDistributor);\\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n }\\n\\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the Comptroller\\n * @dev Only callable by the admin\\n * @param newOracle Address of the new price oracle to set\\n * @custom:event Emits NewPriceOracle on success\\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n */\\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n ensureNonzeroAddress(address(newOracle));\\n\\n ResilientOracleInterface oldOracle = oracle;\\n oracle = newOracle;\\n emit NewPriceOracle(oldOracle, newOracle);\\n }\\n\\n /**\\n * @notice Set the for loop iteration limit to avoid DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n * @return shortfall Account shortfall below liquidation threshold requirements\\n */\\n function getAccountLiquidity(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine the current account liquidity with respect to collateral requirements\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n * @param account The account get liquidity for\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Account liquidity in excess of collateral requirements,\\n * @return shortfall Account shortfall below collateral requirements\\n */\\n function getBorrowingPower(address account)\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n * @return shortfall Hypothetical account shortfall below collateral requirements\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n )\\n external\\n view\\n returns (\\n uint256 error,\\n uint256 liquidity,\\n uint256 shortfall\\n )\\n {\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount,\\n _getCollateralFactor\\n );\\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\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 markets The list of market addresses\\n */\\n function getAllMarkets() external view override returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Check if a market is marked as listed (active)\\n * @param vToken vToken Address for the market to check\\n * @return listed True if listed otherwise false\\n */\\n function isMarketListed(VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].isListed;\\n }\\n\\n /*** Assets You Are In ***/\\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 list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n VToken[] memory assetsIn = accountAssets[account];\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in a given market\\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n * @custom:error PriceError if the oracle returns an invalid price\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n /* Read oracle prices for borrowed and collateral markets */\\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n uint256 seizeTokens;\\n Exp memory numerator;\\n Exp memory denominator;\\n Exp memory ratio;\\n\\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n ratio = div_(numerator, denominator);\\n\\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n return (NO_ERROR, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns reward speed given a vToken\\n * @param vToken The vToken to get the reward speeds for\\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n */\\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n address rewardToken = address(rewardsDistributor.rewardToken());\\n rewardSpeeds[i] = RewardSpeeds({\\n rewardToken: rewardToken,\\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n });\\n }\\n return rewardSpeeds;\\n }\\n\\n /**\\n * @notice Return all reward distributors for this pool\\n * @return Array of RewardDistributor addresses\\n */\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n return rewardsDistributors;\\n }\\n\\n /**\\n * @notice A marker method that returns true for a valid Comptroller contract\\n * @return Always true\\n */\\n function isComptroller() external pure override returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Update the prices of all the tokens associated with the provided account\\n * @param account Address of the account to get associated tokens with\\n */\\n function updatePrices(address account) public {\\n VToken[] memory vTokens = accountAssets[account];\\n uint256 vTokensCount = vTokens.length;\\n\\n ResilientOracleInterface oracle_ = oracle;\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n oracle_.updatePrice(address(vTokens[i]));\\n }\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param market vToken address\\n * @param action Action to check\\n * @return paused True if the action is paused otherwise false\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][action];\\n }\\n\\n /**\\n * @notice Check if a vToken market has been deprecated\\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\\n * @param vToken The market to check if deprecated\\n * @return deprecated True if the given vToken market has been deprecated\\n */\\n function isDeprecated(VToken vToken) public view returns (bool) {\\n return\\n markets[address(vToken)].collateralFactorMantissa == 0 &&\\n actionPaused(address(vToken), Action.BORROW) &&\\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\\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 */\\n function _addToMarket(VToken vToken, address borrower) internal {\\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n\\n if (!marketToJoin.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return;\\n }\\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\\n /**\\n * @notice Internal function to validate that a market hasn't already been added\\n * and if it hasn't adds it\\n * @param vToken The market to support\\n */\\n function _addMarket(address vToken) internal {\\n uint256 marketsCount = allMarkets.length;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n if (allMarkets[i] == VToken(vToken)) {\\n revert MarketAlreadyListed(vToken);\\n }\\n }\\n allMarkets.push(VToken(vToken));\\n marketsCount = allMarkets.length;\\n _ensureMaxLoops(marketsCount);\\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 _setActionPaused(\\n address market,\\n Action action,\\n bool paused\\n ) internal {\\n require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n _actionPaused[market][action] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n * @param vToken Address of the vTokens to redeem\\n * @param redeemer Account redeeming the tokens\\n * @param redeemTokens The number of tokens to redeem\\n */\\n function _checkRedeemAllowed(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal {\\n Market storage market = markets[vToken];\\n\\n if (!market.isListed) {\\n revert MarketNotListed(address(vToken));\\n }\\n\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!market.accountMembership[redeemer]) {\\n return;\\n }\\n\\n // Update the prices of tokens\\n updatePrices(redeemer);\\n\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0,\\n _getCollateralFactor\\n );\\n if (snapshot.shortfall > 0) {\\n revert InsufficientLiquidity();\\n }\\n }\\n\\n /**\\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n * @param account The account to get the snapshot for\\n * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\\n internal\\n view\\n returns (AccountLiquiditySnapshot memory snapshot)\\n {\\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n }\\n\\n /**\\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n liquidation threshold. Accepts the address of the VToken and returns the weight\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return snapshot Account liquidity snapshot\\n */\\n function _getHypotheticalLiquiditySnapshot(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount,\\n function(VToken) internal view returns (Exp memory) weight\\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n // For each asset the account is in\\n VToken[] memory assets = accountAssets[account];\\n uint256 assetsCount = assets.length;\\n\\n for (uint256 i; i < assetsCount; ++i) {\\n VToken asset = assets[i];\\n\\n // Read the balances and exchange rate from the vToken\\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n asset,\\n account\\n );\\n\\n // Get the normalized price of the asset\\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n // Pre-compute conversion factors from vTokens -> usd\\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n weightedVTokenPrice,\\n vTokenBalance,\\n snapshot.weightedCollateral\\n );\\n\\n // totalCollateral += vTokenPrice * vTokenBalance\\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n // borrows += oraclePrice * borrowBalance\\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n // Calculate effects of interacting with vTokenModify\\n if (asset == vTokenModify) {\\n // redeem effect\\n // effects += tokensToDenom * redeemTokens\\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n // borrow effect\\n // effects += oraclePrice * borrowAmount\\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n }\\n }\\n\\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n // These are safe, as the underflow condition is checked first\\n unchecked {\\n if (snapshot.weightedCollateral > borrowPlusEffects) {\\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n snapshot.shortfall = 0;\\n } else {\\n snapshot.liquidity = 0;\\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n }\\n }\\n\\n return snapshot;\\n }\\n\\n /**\\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n * @param asset Address for asset to query price\\n * @return Underlying price\\n */\\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n if (oraclePriceMantissa == 0) {\\n revert PriceError(address(asset));\\n }\\n return oraclePriceMantissa;\\n }\\n\\n /**\\n * @dev Return collateral factor for a market\\n * @param asset Address for asset\\n * @return Collateral factor as exponential\\n */\\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n }\\n\\n /**\\n * @dev Retrieves liquidation threshold for a market as an exponential\\n * @param asset Address for asset to liquidation threshold\\n * @return Liquidation threshold as exponential\\n */\\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n }\\n\\n /**\\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n * @param vToken Market to query\\n * @param user Account address\\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n * @return borrowBalance Borrowed amount, including the interest\\n * @return exchangeRateMantissa Stored exchange rate\\n */\\n function _safeGetAccountSnapshot(VToken vToken, address user)\\n internal\\n view\\n returns (\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRateMantissa\\n )\\n {\\n uint256 err;\\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n if (err != 0) {\\n revert SnapshotError(address(vToken), user);\\n }\\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /// @notice Reverts if the call is not from expectedSender\\n /// @param expectedSender Expected transaction sender\\n function _checkSenderIs(address expectedSender) internal view {\\n if (msg.sender != expectedSender) {\\n revert UnexpectedSender(expectedSender, msg.sender);\\n }\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n /// @param market Market to check\\n /// @param action Action to check\\n function _checkActionPauseState(address market, Action action) private view {\\n if (actionPaused(market, action)) {\\n revert ActionPaused(market, action);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x73fdb4e4b2a2cfec75b0ef5a19491c4136a7953e1239989fb77ed26c1b7a77ac\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n /*** Policy Hooks ***/\\n\\n function preMintHook(\\n address vToken,\\n address minter,\\n uint256 mintAmount\\n ) external;\\n\\n function preRedeemHook(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) external;\\n\\n function preBorrowHook(\\n address vToken,\\n address borrower,\\n uint256 borrowAmount\\n ) external;\\n\\n function preRepayHook(address vToken, address borrower) external;\\n\\n function preLiquidateHook(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address borrower,\\n uint256 repayAmount,\\n bool skipLiquidityCheck\\n ) external;\\n\\n function preSeizeHook(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower\\n ) external;\\n\\n function preTransferHook(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external;\\n\\n function isComptroller() external view returns (bool);\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 repayAmount\\n ) external view returns (uint256, uint256);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n function markets(address) external view returns (bool, uint256);\\n\\n function oracle() external view returns (ResilientOracleInterface);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function closeFactorMantissa() external view returns (uint256);\\n\\n function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n function minLiquidatableCollateral() external view returns (uint256);\\n\\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function borrowCaps(address) external view returns (uint256);\\n\\n function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x0ac4cc1e962946a665033bc50251c33ce59998e492d9f4a76cf0231bf0b0f545\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n struct LiquidationOrder {\\n VToken vTokenCollateral;\\n VToken vTokenBorrowed;\\n uint256 repayAmount;\\n }\\n\\n struct AccountLiquiditySnapshot {\\n uint256 totalCollateral;\\n uint256 weightedCollateral;\\n uint256 borrows;\\n uint256 effects;\\n uint256 liquidity;\\n uint256 shortfall;\\n }\\n\\n struct RewardSpeeds {\\n address rewardToken;\\n uint256 supplySpeed;\\n uint256 borrowSpeed;\\n }\\n\\n struct Market {\\n // Whether or not this market is listed\\n bool isListed;\\n // 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 uint256 collateralFactorMantissa;\\n // Multiplier representing the collateralization after which the borrow is eligible\\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n // value. Must be between 0 and collateral factor, stored as a mantissa.\\n uint256 liquidationThresholdMantissa;\\n // Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n }\\n\\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 /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n ResilientOracleInterface 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 Per-account mapping of \\\"assets you are in\\\"\\n */\\n mapping(address => VToken[]) public accountAssets;\\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 /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n mapping(address => uint256) public borrowCaps;\\n\\n /// @notice Minimal collateral required for regular (non-batch) liquidations\\n uint256 public minLiquidatableCollateral;\\n\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n mapping(address => uint256) public supplyCaps;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n // List of Reward Distributors added\\n RewardsDistributor[] internal rewardsDistributors;\\n\\n // Used to check if rewards distributor is added\\n mapping(address => bool) internal rewardsDistributorExists;\\n\\n uint256 internal constant NO_ERROR = 0;\\n\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\\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[50] private __gap;\\n}\\n\",\"keccak256\":\"0x23a035905b74bfbc8840b76690490a67b8861b2025f109fb5ac9fac13be909d3\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n error TransferNotAllowed();\\n\\n error MintFreshnessCheck();\\n\\n error RedeemFreshnessCheck();\\n error RedeemTransferOutNotPossible();\\n\\n error BorrowFreshnessCheck();\\n error BorrowCashNotAvailable();\\n\\n error RepayBorrowFreshnessCheck();\\n\\n error HealBorrowUnauthorized();\\n error ForceLiquidateBorrowUnauthorized();\\n\\n error LiquidateFreshnessCheck();\\n error LiquidateCollateralFreshnessCheck();\\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n error LiquidateLiquidatorIsBorrower();\\n error LiquidateCloseAmountIsZero();\\n error LiquidateCloseAmountIsUintMax();\\n\\n error LiquidateSeizeLiquidatorIsBorrower();\\n\\n error ProtocolSeizeShareTooBig();\\n\\n error SetReserveFactorFreshCheck();\\n error SetReserveFactorBoundsCheck();\\n\\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n error ReduceReservesFreshCheck();\\n error ReduceReservesCashNotAvailable();\\n error ReduceReservesCashValidation();\\n\\n error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x3f8ec4e18bca1fdf8619966f4f6e095e205517a78f8c741b87fe82125754f96f\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\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 struct Exp {\\n uint256 mantissa;\\n }\\n\\n struct Double {\\n uint256 mantissa;\\n }\\n\\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n uint256 internal constant DOUBLE_SCALE = 1e36;\\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint256) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / EXP_SCALE;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\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 // solhint-disable-next-line func-name-mixedcase\\n function mul_ScalarTruncateAddUInt(\\n Exp memory a,\\n uint256 scalar,\\n uint256 addend\\n ) internal pure returns (uint256) {\\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n require(n <= type(uint224).max, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\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_(uint256 a, uint256 b) internal pure returns (uint256) {\\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) / EXP_SCALE });\\n }\\n\\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / EXP_SCALE;\\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) / DOUBLE_SCALE });\\n }\\n\\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n }\\n\\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n }\\n\\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n }\\n}\\n\",\"keccak256\":\"0xc13fcd089aa939e53b9c494c24beed316d572e9d433a44034eefa77915b673ec\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\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 amount of reserves the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\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 amount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @param badDebt The amount of badDebt in the market\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa,\\n uint256 badDebt\\n ) external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n * @return Always true\\n */\\n function isInterestRateModel() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x60ea8b0b70165acc3cf0f1e92f8dcea93ef5ddc2b8b99172799594aeec7c22b5\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n // Limit for the loops to avoid the DOS\\n uint256 public maxLoopsLimit;\\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 max loops limit is set\\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function _setMaxLoopsLimit(uint256 limit) internal {\\n require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n maxLoopsLimit = limit;\\n\\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n }\\n\\n /**\\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n * @param len Length of the loops iterate\\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n */\\n function _ensureMaxLoops(uint256 len) internal view {\\n if (len > maxLoopsLimit) {\\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x98c97af128677629375ca93e8d8ca3f337a4abf9304a0a4ddaea9d96cc554c3b\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { PoolRegistryInterface } from \\\"./PoolRegistryInterface.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\n\\n/**\\n * @title PoolRegistry\\n * @author Venus\\n * @notice The Isolated Pools architecture centers around the `PoolRegistry` contract. The `PoolRegistry` maintains a directory of isolated lending\\n * pools and can perform actions like creating and registering new pools, adding new markets to existing pools, setting and updating the pool's required\\n * metadata, and providing the getter methods to get information on the pools.\\n *\\n * Isolated lending has three main components: PoolRegistry, pools, and markets. The PoolRegistry is responsible for managing pools.\\n * It can create new pools, update pool metadata and manage markets within pools. PoolRegistry contains getter methods to get the details of\\n * any existing pool like `getVTokenForAsset` and `getPoolsSupportedByAsset`. It also contains methods for updating pool metadata (`updatePoolMetadata`)\\n * and setting pool name (`setPoolName`).\\n *\\n * The directory of pools is managed through two mappings: `_poolByComptroller` which is a hashmap with the comptroller address as the key and `VenusPool` as\\n * the value and `_poolsByID` which is an array of comptroller addresses. Individual pools can be accessed by calling `getPoolByComptroller` with the pool's\\n * comptroller address. `_poolsByID` is used to iterate through all of the pools.\\n *\\n * PoolRegistry also contains a map of asset addresses called `_supportedPools` that maps to an array of assets suppored by each pool. This array of pools by\\n * asset is retrieved by calling `getPoolsSupportedByAsset`.\\n *\\n * PoolRegistry registers new isolated pools in the directory with the `createRegistryPool` method. Isolated pools are composed of independent markets with\\n * specific assets and custom risk management configurations according to their markets.\\n */\\ncontract PoolRegistry is Ownable2StepUpgradeable, AccessControlledV8, PoolRegistryInterface {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct AddMarketInput {\\n VToken vToken;\\n uint256 collateralFactor;\\n uint256 liquidationThreshold;\\n uint256 initialSupply;\\n address vTokenReceiver;\\n uint256 supplyCap;\\n uint256 borrowCap;\\n }\\n\\n uint256 internal constant MAX_POOL_NAME_LENGTH = 100;\\n\\n /**\\n * @notice Maps pool's comptroller address to metadata.\\n */\\n mapping(address => VenusPoolMetaData) public metadata;\\n\\n /**\\n * @dev Maps pool ID to pool's comptroller address\\n */\\n mapping(uint256 => address) private _poolsByID;\\n\\n /**\\n * @dev Total number of pools created.\\n */\\n uint256 private _numberOfPools;\\n\\n /**\\n * @dev Maps comptroller address to Venus pool Index.\\n */\\n mapping(address => VenusPool) private _poolByComptroller;\\n\\n /**\\n * @dev Maps pool's comptroller address to asset to vToken.\\n */\\n mapping(address => mapping(address => address)) private _vTokens;\\n\\n /**\\n * @dev Maps asset to list of supported pools.\\n */\\n mapping(address => address[]) private _supportedPools;\\n\\n /**\\n * @notice Emitted when a new Venus pool is added to the directory.\\n */\\n event PoolRegistered(address indexed comptroller, VenusPool pool);\\n\\n /**\\n * @notice Emitted when a pool name is set.\\n */\\n event PoolNameSet(address indexed comptroller, string oldName, string newName);\\n\\n /**\\n * @notice Emitted when a pool metadata is updated.\\n */\\n event PoolMetadataUpdated(\\n address indexed comptroller,\\n VenusPoolMetaData oldMetadata,\\n VenusPoolMetaData newMetadata\\n );\\n\\n /**\\n * @notice Emitted when a Market is added to the pool.\\n */\\n event MarketAdded(address indexed comptroller, address indexed vTokenAddress);\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializes the deployer to owner\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(address accessControlManager_) external initializer {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n }\\n\\n /**\\n * @notice Adds a new Venus pool to the directory\\n * @dev Price oracle must be configured before adding a pool\\n * @param name The name of the pool\\n * @param comptroller Pool's Comptroller contract\\n * @param closeFactor The pool's close factor (scaled by 1e18)\\n * @param liquidationIncentive The pool's liquidation incentive (scaled by 1e18)\\n * @param minLiquidatableCollateral Minimal collateral for regular (non-batch) liquidations flow\\n * @return index The index of the registered Venus pool\\n * @custom:error ZeroAddressNotAllowed is thrown when Comptroller address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when price oracle address is zero\\n */\\n function addPool(\\n string calldata name,\\n Comptroller comptroller,\\n uint256 closeFactor,\\n uint256 liquidationIncentive,\\n uint256 minLiquidatableCollateral\\n ) external virtual returns (uint256 index) {\\n _checkAccessAllowed(\\\"addPool(string,address,uint256,uint256,uint256)\\\");\\n // Input validation\\n ensureNonzeroAddress(address(comptroller));\\n ensureNonzeroAddress(address(comptroller.oracle()));\\n\\n uint256 poolId = _registerPool(name, address(comptroller));\\n\\n // Set Venus pool parameters\\n comptroller.setCloseFactor(closeFactor);\\n comptroller.setLiquidationIncentive(liquidationIncentive);\\n comptroller.setMinLiquidatableCollateral(minLiquidatableCollateral);\\n\\n return poolId;\\n }\\n\\n /**\\n * @notice Add a market to an existing pool and then mint to provide initial supply\\n * @param input The structure describing the parameters for adding a market to a pool\\n * @custom:error ZeroAddressNotAllowed is thrown when vToken address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when vTokenReceiver address is zero\\n */\\n function addMarket(AddMarketInput memory input) external {\\n _checkAccessAllowed(\\\"addMarket(AddMarketInput)\\\");\\n ensureNonzeroAddress(address(input.vToken));\\n ensureNonzeroAddress(input.vTokenReceiver);\\n require(input.initialSupply > 0, \\\"PoolRegistry: initialSupply is zero\\\");\\n\\n VToken vToken = input.vToken;\\n address vTokenAddress = address(vToken);\\n address comptrollerAddress = address(vToken.comptroller());\\n Comptroller comptroller = Comptroller(comptrollerAddress);\\n address underlyingAddress = vToken.underlying();\\n IERC20Upgradeable underlying = IERC20Upgradeable(underlyingAddress);\\n\\n require(_poolByComptroller[comptrollerAddress].creator != address(0), \\\"PoolRegistry: Pool not registered\\\");\\n // solhint-disable-next-line reason-string\\n require(\\n _vTokens[comptrollerAddress][underlyingAddress] == address(0),\\n \\\"PoolRegistry: Market already added for asset comptroller combination\\\"\\n );\\n\\n comptroller.supportMarket(vToken);\\n comptroller.setCollateralFactor(vToken, input.collateralFactor, input.liquidationThreshold);\\n\\n uint256[] memory newSupplyCaps = new uint256[](1);\\n uint256[] memory newBorrowCaps = new uint256[](1);\\n VToken[] memory vTokens = new VToken[](1);\\n\\n newSupplyCaps[0] = input.supplyCap;\\n newBorrowCaps[0] = input.borrowCap;\\n vTokens[0] = vToken;\\n\\n comptroller.setMarketSupplyCaps(vTokens, newSupplyCaps);\\n comptroller.setMarketBorrowCaps(vTokens, newBorrowCaps);\\n\\n _vTokens[comptrollerAddress][underlyingAddress] = vTokenAddress;\\n _supportedPools[underlyingAddress].push(comptrollerAddress);\\n\\n uint256 amountToSupply = _transferIn(underlying, msg.sender, input.initialSupply);\\n underlying.approve(vTokenAddress, 0);\\n underlying.approve(vTokenAddress, amountToSupply);\\n vToken.mintBehalf(input.vTokenReceiver, amountToSupply);\\n\\n emit MarketAdded(comptrollerAddress, vTokenAddress);\\n }\\n\\n /**\\n * @notice Modify existing Venus pool name\\n * @param comptroller Pool's Comptroller\\n * @param name New pool name\\n */\\n function setPoolName(address comptroller, string calldata name) external {\\n _checkAccessAllowed(\\\"setPoolName(address,string)\\\");\\n _ensureValidName(name);\\n VenusPool storage pool = _poolByComptroller[comptroller];\\n string memory oldName = pool.name;\\n pool.name = name;\\n emit PoolNameSet(comptroller, oldName, name);\\n }\\n\\n /**\\n * @notice Update metadata of an existing pool\\n * @param comptroller Pool's Comptroller\\n * @param metadata_ New pool metadata\\n */\\n function updatePoolMetadata(address comptroller, VenusPoolMetaData calldata metadata_) external {\\n _checkAccessAllowed(\\\"updatePoolMetadata(address,VenusPoolMetaData)\\\");\\n VenusPoolMetaData memory oldMetadata = metadata[comptroller];\\n metadata[comptroller] = metadata_;\\n emit PoolMetadataUpdated(comptroller, oldMetadata, metadata_);\\n }\\n\\n /**\\n * @notice Returns arrays of all Venus pools' data\\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\\n * @return A list of all pools within PoolRegistry, with details for each pool\\n */\\n function getAllPools() external view override returns (VenusPool[] memory) {\\n uint256 numberOfPools_ = _numberOfPools; // storage load to save gas\\n VenusPool[] memory _pools = new VenusPool[](numberOfPools_);\\n for (uint256 i = 1; i <= numberOfPools_; ++i) {\\n address comptroller = _poolsByID[i];\\n _pools[i - 1] = (_poolByComptroller[comptroller]);\\n }\\n return _pools;\\n }\\n\\n /**\\n * @param comptroller The comptroller proxy address associated to the pool\\n * @return Returns Venus pool\\n */\\n function getPoolByComptroller(address comptroller) external view override returns (VenusPool memory) {\\n return _poolByComptroller[comptroller];\\n }\\n\\n /**\\n * @param comptroller comptroller of Venus pool\\n * @return Returns Metadata of Venus pool\\n */\\n function getVenusPoolMetadata(address comptroller) external view override returns (VenusPoolMetaData memory) {\\n return metadata[comptroller];\\n }\\n\\n function getVTokenForAsset(address comptroller, address asset) external view override returns (address) {\\n return _vTokens[comptroller][asset];\\n }\\n\\n function getPoolsSupportedByAsset(address asset) external view override returns (address[] memory) {\\n return _supportedPools[asset];\\n }\\n\\n /**\\n * @dev Adds a new Venus pool to the directory (without checking msg.sender).\\n * @param name The name of the pool\\n * @param comptroller The pool's Comptroller proxy contract address\\n * @return The index of the registered Venus pool\\n */\\n function _registerPool(string calldata name, address comptroller) internal returns (uint256) {\\n VenusPool storage storedPool = _poolByComptroller[comptroller];\\n\\n require(storedPool.creator == address(0), \\\"PoolRegistry: Pool already exists in the directory.\\\");\\n _ensureValidName(name);\\n\\n ++_numberOfPools;\\n uint256 numberOfPools_ = _numberOfPools; // cache on stack to save storage read gas\\n\\n VenusPool memory pool = VenusPool(name, msg.sender, comptroller, block.number, block.timestamp);\\n\\n _poolsByID[numberOfPools_] = comptroller;\\n _poolByComptroller[comptroller] = pool;\\n\\n emit PoolRegistered(comptroller, pool);\\n return numberOfPools_;\\n }\\n\\n function _transferIn(\\n IERC20Upgradeable token,\\n address from,\\n uint256 amount\\n ) internal returns (uint256) {\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n return balanceAfter - balanceBefore;\\n }\\n\\n function _ensureValidName(string calldata name) internal pure {\\n require(bytes(name).length <= MAX_POOL_NAME_LENGTH, \\\"Pool's name is too large\\\");\\n }\\n}\\n\",\"keccak256\":\"0x6b903c298c9e2c3aaed29b4a1f76ace9fc24e50a48db22111bfc190a1a25c499\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title PoolRegistryInterface\\n * @author Venus\\n * @notice Interface implemented by `PoolRegistry`.\\n */\\ninterface PoolRegistryInterface {\\n /**\\n * @notice Struct for a Venus interest rate pool.\\n */\\n struct VenusPool {\\n string name;\\n address creator;\\n address comptroller;\\n uint256 blockPosted;\\n uint256 timestampPosted;\\n }\\n\\n /**\\n * @notice Struct for a Venus interest rate pool metadata.\\n */\\n struct VenusPoolMetaData {\\n string category;\\n string logoURL;\\n string description;\\n }\\n\\n /// @notice Get all pools in PoolRegistry\\n function getAllPools() external view returns (VenusPool[] memory);\\n\\n /// @notice Get a pool by comptroller address\\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\\n\\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\\n\\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\\n\\n /// @notice Get the metadata of a Pool by comptroller address\\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\\n}\\n\",\"keccak256\":\"0x7e8ccd190ef019a3f8c3fcb67ed3eadd7bed32b263f88566870d138cd95ae312\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each block for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n struct RewardToken {\\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n uint224 index;\\n // The block number the index was last updated at\\n uint32 block;\\n // The block number at which to stop rewards\\n uint32 lastRewardingBlock;\\n }\\n\\n /// @notice The initial REWARD TOKEN index for a market\\n uint224 public constant INITIAL_INDEX = 1e36;\\n\\n /// @notice The REWARD TOKEN market supply state for each market\\n mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n mapping(address => uint256) public rewardTokenAccrued;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n /// @notice The REWARD TOKEN market borrow state for each market\\n mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\\n mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\\n mapping(address => uint256) public lastContributorBlock;\\n\\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n Comptroller private comptroller;\\n\\n IERC20Upgradeable public rewardToken;\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n event DistributedSupplierRewardToken(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenSupplyIndex\\n );\\n\\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n event DistributedBorrowerRewardToken(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 rewardTokenDelta,\\n uint256 rewardTokenTotal,\\n uint256 rewardTokenBorrowIndex\\n );\\n\\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when REWARD TOKEN is granted by admin\\n event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n /// @notice Emitted when a market is initialized\\n event MarketInitialized(address indexed vToken);\\n\\n /// @notice Emitted when a reward token supply index is updated\\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n /// @notice Emitted when a reward token borrow index is updated\\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n /// @notice Emitted when a reward for contributor is updated\\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n /// @notice Emitted when a reward token last rewarding block for supply is updated\\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n modifier onlyComptroller() {\\n require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n _;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice RewardsDistributor initializer\\n * @dev Initializes the deployer to owner\\n * @param comptroller_ Comptroller to attach the reward distributor to\\n * @param rewardToken_ Reward token to distribute\\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n * @param accessControlManager_ AccessControlManager contract address\\n */\\n function initialize(\\n Comptroller comptroller_,\\n IERC20Upgradeable rewardToken_,\\n uint256 loopsLimit_,\\n address accessControlManager_\\n ) external initializer {\\n comptroller = comptroller_;\\n rewardToken = rewardToken_;\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n\\n _setMaxLoopsLimit(loopsLimit_);\\n }\\n\\n function initializeMarket(address vToken) external onlyComptroller {\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = INITIAL_INDEX;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n\\n emit MarketInitialized(vToken);\\n }\\n\\n /*** Reward Token Distribution ***/\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n * Borrowers will begin to accrue after the first interaction with the protocol.\\n * @dev This function should only be called when the user has a borrow position in the market\\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) external onlyComptroller {\\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n }\\n\\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n _updateRewardTokenSupplyIndex(vToken);\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the recipient\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n */\\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n uint256 amountLeft = _grantRewardToken(recipient, amount);\\n require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n emit RewardTokenGranted(recipient, amount);\\n }\\n\\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN speed to update\\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n */\\n function setRewardTokenSpeeds(\\n VToken[] memory vTokens,\\n uint256[] memory supplySpeeds,\\n uint256[] memory borrowSpeeds\\n ) external {\\n _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n */\\n function setLastRewardingBlocks(\\n VToken[] calldata vTokens,\\n uint32[] calldata supplyLastRewardingBlocks,\\n uint32[] calldata borrowLastRewardingBlocks\\n ) external {\\n _checkAccessAllowed(\\\"setLastRewardingBlock(address[],uint32[],uint32[])\\\");\\n uint256 numTokens = vTokens.length;\\n require(\\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n );\\n\\n for (uint256 i; i < numTokens; ) {\\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single contributor\\n * @param contributor The contributor whose REWARD TOKEN speed to update\\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n */\\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n updateContributorRewards(contributor);\\n if (rewardTokenSpeed == 0) {\\n // release storage\\n delete lastContributorBlock[contributor];\\n } else {\\n lastContributorBlock[contributor] = getBlockNumber();\\n }\\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n }\\n\\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n _distributeSupplierRewardToken(vToken, supplier);\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in all markets\\n * @param holder The address to claim REWARD TOKEN for\\n */\\n function claimRewardToken(address holder) external {\\n return claimRewardToken(holder, comptroller.getAllMarkets());\\n }\\n\\n /**\\n * @notice Set the limit for the loops can iterate to avoid the DOS\\n * @param limit Limit for the max loops can execute at a time\\n */\\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n _setMaxLoopsLimit(limit);\\n }\\n\\n /**\\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n * @param contributor The address to calculate contributor rewards for\\n */\\n function updateContributorRewards(address contributor) public {\\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n uint256 blockNumber = getBlockNumber();\\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n rewardTokenAccrued[contributor] = contributorAccrued;\\n lastContributorBlock[contributor] = blockNumber;\\n\\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n }\\n }\\n\\n /**\\n * @notice Claim all the rewardToken accrued by holder in the specified markets\\n * @param holder The address to claim REWARD TOKEN for\\n * @param vTokens The list of markets to claim REWARD TOKEN in\\n */\\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n uint256 vTokensCount = vTokens.length;\\n\\n _ensureMaxLoops(vTokensCount);\\n\\n for (uint256 i; i < vTokensCount; ++i) {\\n VToken vToken = vTokens[i];\\n require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n _updateRewardTokenSupplyIndex(address(vToken));\\n _distributeSupplierRewardToken(address(vToken), holder);\\n }\\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n }\\n\\n function getBlockNumber() public view virtual returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN last rewarding block for a single market.\\n * @param vToken market's whose reward token last rewarding block to be updated\\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n */\\n function _setLastRewardingBlock(\\n VToken vToken,\\n uint32 supplyLastRewardingBlock,\\n uint32 borrowLastRewardingBlock\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n uint256 blockNumber = getBlockNumber();\\n\\n require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n require(\\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n require(\\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n \\\"this RewardsDistributor is already locked\\\"\\n );\\n\\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n }\\n\\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n }\\n }\\n\\n /**\\n * @notice Set REWARD TOKEN speed for a single market.\\n * @param vToken market's whose reward token rate to be updated\\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n */\\n function _setRewardTokenSpeed(\\n VToken vToken,\\n uint256 supplySpeed,\\n uint256 borrowSpeed\\n ) internal {\\n require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n _updateRewardTokenSupplyIndex(address(vToken));\\n\\n // Update speed and emit event\\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. REWARD TOKEN accrued properly for the old speed, and\\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n\\n /**\\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\\n */\\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplyIndex = supplyState.index;\\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n * @param marketBorrowIndex The current global borrow index of vToken\\n */\\n function _distributeBorrowerRewardToken(\\n address vToken,\\n address borrower,\\n Exp memory marketBorrowIndex\\n ) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowIndex = borrowState.index;\\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = INITIAL_INDEX;\\n }\\n\\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n if (borrowerAmount != 0) {\\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n }\\n }\\n\\n /**\\n * @notice Transfer REWARD TOKEN to the user.\\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n * @param user The address of the user to transfer REWARD TOKEN to\\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n */\\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n if (amount > 0 && amount <= rewardTokenRemaining) {\\n rewardToken.safeTransfer(user, amount);\\n return 0;\\n }\\n return amount;\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenSupplyIndex(address vToken) internal {\\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\\n blockNumber = supplyState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\\n\\n if (deltaBlocks > 0 && supplySpeed > 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens > 0\\n ? fraction(accruedSinceUpdate, supplyTokens)\\n : Double({ mantissa: 0 });\\n supplyState.index = safe224(\\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n supplyState.block = blockNumber;\\n }\\n\\n emit RewardTokenSupplyIndexUpdated(vToken);\\n }\\n\\n /**\\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n * @param marketBorrowIndex The current global borrow index of vToken\\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n */\\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n uint32 blockNumber = safe32(getBlockNumber(), \\\"block number exceeds 32 bits\\\");\\n\\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\\n blockNumber = borrowState.lastRewardingBlock;\\n }\\n\\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\\n if (deltaBlocks > 0 && borrowSpeed > 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount > 0\\n ? fraction(accruedSinceUpdate, borrowAmount)\\n : Double({ mantissa: 0 });\\n borrowState.index = safe224(\\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\\n \\\"new index exceeds 224 bits\\\"\\n );\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks > 0) {\\n borrowState.block = blockNumber;\\n }\\n\\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0x0e5bede4edc4346e689de0adcf98dc9642feb55d44c1916715741c5937a34d52\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IProtocolShareReserve\\n * @author Venus\\n * @notice Interface implemented by `ProtocolShareReserve`.\\n */\\ninterface IProtocolShareReserve {\\n function updateAssetsState(address comptroller, address asset) external;\\n}\\n\",\"keccak256\":\"0x45bf43fe09973ebfe0b5d3e81f966d7521b88c118d6ff64c289c500a62a7d564\",\"license\":\"BSD-3-Clause\"},\"contracts/RiskFund/IRiskFund.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/**\\n * @title IRiskFund\\n * @author Venus\\n * @notice Interface implemented by `RiskFund`.\\n */\\ninterface IRiskFund {\\n function swapPoolsAssets(\\n address[] calldata markets,\\n uint256[] calldata amountsOutMin,\\n address[][] calldata paths,\\n uint256 deadline\\n ) external returns (uint256);\\n\\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\\n\\n function updateAssetsState(address comptroller, address asset) external;\\n\\n function convertibleBaseAsset() external view returns (address);\\n\\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xa519791948d96fb81143cdd9db0a2b753a39f1f9ca4e8c68b92997e2095f241a\",\"license\":\"BSD-3-Clause\"},\"contracts/Shortfall/Shortfall.sol\":{\"content\":\"/// @notice SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { ReentrancyGuardUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"../ComptrollerInterface.sol\\\";\\nimport { IRiskFund } from \\\"../RiskFund/IRiskFund.sol\\\";\\nimport { PoolRegistry } from \\\"../Pool/PoolRegistry.sol\\\";\\nimport { PoolRegistryInterface } from \\\"../Pool/PoolRegistryInterface.sol\\\";\\nimport { TokenDebtTracker } from \\\"../lib/TokenDebtTracker.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"../lib/validators.sol\\\";\\nimport { EXP_SCALE } from \\\"../lib/constants.sol\\\";\\n\\n/**\\n * @title Shortfall\\n * @author Venus\\n * @notice Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset`\\n * is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value.\\n * This value is set and can be changed by the authorized accounts. If the pool\\u2019s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner\\n * is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise,\\n * if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the\\n * risk fund in exchange for paying off all the pool's bad debt.\\n */\\ncontract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGuardUpgradeable, TokenDebtTracker {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /// @notice Type of auction\\n enum AuctionType {\\n LARGE_POOL_DEBT,\\n LARGE_RISK_FUND\\n }\\n\\n /// @notice Status of auction\\n enum AuctionStatus {\\n NOT_STARTED,\\n STARTED,\\n ENDED\\n }\\n\\n /// @notice Auction metadata\\n struct Auction {\\n uint256 startBlock;\\n AuctionType auctionType;\\n AuctionStatus status;\\n VToken[] markets;\\n uint256 seizedRiskFund;\\n address highestBidder;\\n uint256 highestBidBps;\\n uint256 highestBidBlock;\\n uint256 startBidBps;\\n mapping(VToken => uint256) marketDebt;\\n mapping(VToken => uint256) bidAmount;\\n }\\n\\n /// @dev Max basis points i.e., 100%\\n uint256 private constant MAX_BPS = 10000;\\n\\n uint256 private constant DEFAULT_NEXT_BIDDER_BLOCK_LIMIT = 100;\\n\\n uint256 private constant DEFAULT_WAIT_FOR_FIRST_BIDDER = 100;\\n\\n uint256 private constant DEFAULT_INCENTIVE_BPS = 1000; // 10%\\n\\n /// @notice Pool registry address\\n address public poolRegistry;\\n\\n /// @notice Risk fund address\\n IRiskFund public riskFund;\\n\\n /// @notice Minimum USD debt in pool for shortfall to trigger\\n uint256 public minimumPoolBadDebt;\\n\\n /// @notice Incentive to auction participants, initial value set to 1000 or 10%\\n uint256 public incentiveBps;\\n\\n /// @notice Time to wait for next bidder. Initially waits for 100 blocks\\n uint256 public nextBidderBlockLimit;\\n\\n /// @notice Boolean of if auctions are paused\\n bool public auctionsPaused;\\n\\n /// @notice Time to wait for first bidder. Initially waits for 100 blocks\\n uint256 public waitForFirstBidder;\\n\\n /// @notice Auctions for each pool\\n mapping(address => Auction) public auctions;\\n\\n /// @notice Emitted when a auction starts\\n event AuctionStarted(\\n address indexed comptroller,\\n uint256 auctionStartBlock,\\n AuctionType auctionType,\\n VToken[] markets,\\n uint256[] marketsDebt,\\n uint256 seizedRiskFund,\\n uint256 startBidBps\\n );\\n\\n /// @notice Emitted when a bid is placed\\n event BidPlaced(address indexed comptroller, uint256 auctionStartBlock, uint256 bidBps, address indexed bidder);\\n\\n /// @notice Emitted when a auction is completed\\n event AuctionClosed(\\n address indexed comptroller,\\n uint256 auctionStartBlock,\\n address indexed highestBidder,\\n uint256 highestBidBps,\\n uint256 seizedRiskFind,\\n VToken[] markets,\\n uint256[] marketDebt\\n );\\n\\n /// @notice Emitted when a auction is restarted\\n event AuctionRestarted(address indexed comptroller, uint256 auctionStartBlock);\\n\\n /// @notice Emitted when pool registry address is updated\\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\\n\\n /// @notice Emitted when minimum pool bad debt is updated\\n event MinimumPoolBadDebtUpdated(uint256 oldMinimumPoolBadDebt, uint256 newMinimumPoolBadDebt);\\n\\n /// @notice Emitted when wait for first bidder block count is updated\\n event WaitForFirstBidderUpdated(uint256 oldWaitForFirstBidder, uint256 newWaitForFirstBidder);\\n\\n /// @notice Emitted when next bidder block limit is updated\\n event NextBidderBlockLimitUpdated(uint256 oldNextBidderBlockLimit, uint256 newNextBidderBlockLimit);\\n\\n /// @notice Emitted when incentiveBps is updated\\n event IncentiveBpsUpdated(uint256 oldIncentiveBps, uint256 newIncentiveBps);\\n\\n /// @notice Emitted when auctions are paused\\n event AuctionsPaused(address sender);\\n\\n /// @notice Emitted when auctions are unpaused\\n event AuctionsResumed(address sender);\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initialize the shortfall contract\\n * @param riskFund_ RiskFund contract address\\n * @param minimumPoolBadDebt_ Minimum bad debt in base asset for a pool to start auction\\n * @param accessControlManager_ AccessControlManager contract address\\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\\n */\\n function initialize(\\n IRiskFund riskFund_,\\n uint256 minimumPoolBadDebt_,\\n address accessControlManager_\\n ) external initializer {\\n ensureNonzeroAddress(address(riskFund_));\\n require(minimumPoolBadDebt_ != 0, \\\"invalid minimum pool bad debt\\\");\\n\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\n __ReentrancyGuard_init();\\n __TokenDebtTracker_init();\\n minimumPoolBadDebt = minimumPoolBadDebt_;\\n riskFund = riskFund_;\\n waitForFirstBidder = DEFAULT_WAIT_FOR_FIRST_BIDDER;\\n nextBidderBlockLimit = DEFAULT_NEXT_BIDDER_BLOCK_LIMIT;\\n incentiveBps = DEFAULT_INCENTIVE_BPS;\\n auctionsPaused = false;\\n }\\n\\n /**\\n * @notice Place a bid greater than the previous in an ongoing auction\\n * @param comptroller Comptroller address of the pool\\n * @param bidBps The bid percent of the risk fund or bad debt depending on auction type\\n * @param auctionStartBlock The block number when auction started\\n * @custom:event Emits BidPlaced event on success\\n */\\n function placeBid(\\n address comptroller,\\n uint256 bidBps,\\n uint256 auctionStartBlock\\n ) external nonReentrant {\\n Auction storage auction = auctions[comptroller];\\n\\n require(auction.startBlock == auctionStartBlock, \\\"auction has been restarted\\\");\\n require(_isStarted(auction), \\\"no on-going auction\\\");\\n require(!_isStale(auction), \\\"auction is stale, restart it\\\");\\n require(bidBps > 0, \\\"basis points cannot be zero\\\");\\n require(bidBps <= MAX_BPS, \\\"basis points cannot be more than 10000\\\");\\n require(\\n (auction.auctionType == AuctionType.LARGE_POOL_DEBT &&\\n ((auction.highestBidder != address(0) && bidBps > auction.highestBidBps) ||\\n (auction.highestBidder == address(0) && bidBps >= auction.startBidBps))) ||\\n (auction.auctionType == AuctionType.LARGE_RISK_FUND &&\\n ((auction.highestBidder != address(0) && bidBps < auction.highestBidBps) ||\\n (auction.highestBidder == address(0) && bidBps <= auction.startBidBps))),\\n \\\"your bid is not the highest\\\"\\n );\\n\\n uint256 marketsCount = auction.markets.length;\\n for (uint256 i; i < marketsCount; ++i) {\\n VToken vToken = VToken(address(auction.markets[i]));\\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\\n\\n if (auction.highestBidder != address(0)) {\\n _transferOutOrTrackDebt(erc20, auction.highestBidder, auction.bidAmount[auction.markets[i]]);\\n }\\n uint256 balanceBefore = erc20.balanceOf(address(this));\\n\\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\\n uint256 currentBidAmount = ((auction.marketDebt[auction.markets[i]] * bidBps) / MAX_BPS);\\n erc20.safeTransferFrom(msg.sender, address(this), currentBidAmount);\\n } else {\\n erc20.safeTransferFrom(msg.sender, address(this), auction.marketDebt[auction.markets[i]]);\\n }\\n\\n uint256 balanceAfter = erc20.balanceOf(address(this));\\n auction.bidAmount[auction.markets[i]] = balanceAfter - balanceBefore;\\n }\\n\\n auction.highestBidder = msg.sender;\\n auction.highestBidBps = bidBps;\\n auction.highestBidBlock = block.number;\\n\\n emit BidPlaced(comptroller, auction.startBlock, bidBps, msg.sender);\\n }\\n\\n /**\\n * @notice Close an auction\\n * @param comptroller Comptroller address of the pool\\n * @custom:event Emits AuctionClosed event on successful close\\n */\\n function closeAuction(address comptroller) external nonReentrant {\\n Auction storage auction = auctions[comptroller];\\n\\n require(_isStarted(auction), \\\"no on-going auction\\\");\\n require(\\n block.number > auction.highestBidBlock + nextBidderBlockLimit && auction.highestBidder != address(0),\\n \\\"waiting for next bidder. cannot close auction\\\"\\n );\\n\\n uint256 marketsCount = auction.markets.length;\\n uint256[] memory marketsDebt = new uint256[](marketsCount);\\n\\n auction.status = AuctionStatus.ENDED;\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n VToken vToken = VToken(address(auction.markets[i]));\\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\\n\\n uint256 balanceBefore = erc20.balanceOf(address(auction.markets[i]));\\n erc20.safeTransfer(address(auction.markets[i]), auction.bidAmount[auction.markets[i]]);\\n uint256 balanceAfter = erc20.balanceOf(address(auction.markets[i]));\\n marketsDebt[i] = balanceAfter - balanceBefore;\\n\\n auction.markets[i].badDebtRecovered(marketsDebt[i]);\\n }\\n\\n uint256 riskFundBidAmount;\\n\\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\\n riskFundBidAmount = auction.seizedRiskFund;\\n } else {\\n riskFundBidAmount = (auction.seizedRiskFund * auction.highestBidBps) / MAX_BPS;\\n }\\n\\n address convertibleBaseAsset = riskFund.convertibleBaseAsset();\\n\\n uint256 transferredAmount = riskFund.transferReserveForAuction(comptroller, riskFundBidAmount);\\n _transferOutOrTrackDebt(IERC20Upgradeable(convertibleBaseAsset), auction.highestBidder, riskFundBidAmount);\\n\\n emit AuctionClosed(\\n comptroller,\\n auction.startBlock,\\n auction.highestBidder,\\n auction.highestBidBps,\\n transferredAmount,\\n auction.markets,\\n marketsDebt\\n );\\n }\\n\\n /**\\n * @notice Start a auction when there is not currently one active\\n * @param comptroller Comptroller address of the pool\\n * @custom:event Emits AuctionStarted event on success\\n * @custom:event Errors if auctions are paused\\n */\\n function startAuction(address comptroller) external nonReentrant {\\n require(!auctionsPaused, \\\"Auctions are paused\\\");\\n _startAuction(comptroller);\\n }\\n\\n /**\\n * @notice Restart an auction\\n * @param comptroller Address of the pool\\n * @custom:event Emits AuctionRestarted event on successful restart\\n */\\n function restartAuction(address comptroller) external nonReentrant {\\n Auction storage auction = auctions[comptroller];\\n\\n require(!auctionsPaused, \\\"auctions are paused\\\");\\n require(_isStarted(auction), \\\"no on-going auction\\\");\\n require(_isStale(auction), \\\"you need to wait for more time for first bidder\\\");\\n\\n auction.status = AuctionStatus.ENDED;\\n\\n emit AuctionRestarted(comptroller, auction.startBlock);\\n _startAuction(comptroller);\\n }\\n\\n /**\\n * @notice Update next bidder block limit which is used determine when an auction can be closed\\n * @param _nextBidderBlockLimit New next bidder block limit\\n * @custom:event Emits NextBidderBlockLimitUpdated on success\\n * @custom:access Restricted by ACM\\n */\\n function updateNextBidderBlockLimit(uint256 _nextBidderBlockLimit) external {\\n _checkAccessAllowed(\\\"updateNextBidderBlockLimit(uint256)\\\");\\n require(_nextBidderBlockLimit != 0, \\\"_nextBidderBlockLimit must not be 0\\\");\\n uint256 oldNextBidderBlockLimit = nextBidderBlockLimit;\\n nextBidderBlockLimit = _nextBidderBlockLimit;\\n emit NextBidderBlockLimitUpdated(oldNextBidderBlockLimit, _nextBidderBlockLimit);\\n }\\n\\n /**\\n * @notice Updates the incentive BPS\\n * @param _incentiveBps New incentive BPS\\n * @custom:event Emits IncentiveBpsUpdated on success\\n * @custom:access Restricted by ACM\\n */\\n function updateIncentiveBps(uint256 _incentiveBps) external {\\n _checkAccessAllowed(\\\"updateIncentiveBps(uint256)\\\");\\n require(_incentiveBps != 0, \\\"incentiveBps must not be 0\\\");\\n uint256 oldIncentiveBps = incentiveBps;\\n incentiveBps = _incentiveBps;\\n emit IncentiveBpsUpdated(oldIncentiveBps, _incentiveBps);\\n }\\n\\n /**\\n * @notice Update minimum pool bad debt to start auction\\n * @param _minimumPoolBadDebt Minimum bad debt in BUSD for a pool to start auction\\n * @custom:event Emits MinimumPoolBadDebtUpdated on success\\n * @custom:access Restricted by ACM\\n */\\n function updateMinimumPoolBadDebt(uint256 _minimumPoolBadDebt) external {\\n _checkAccessAllowed(\\\"updateMinimumPoolBadDebt(uint256)\\\");\\n uint256 oldMinimumPoolBadDebt = minimumPoolBadDebt;\\n minimumPoolBadDebt = _minimumPoolBadDebt;\\n emit MinimumPoolBadDebtUpdated(oldMinimumPoolBadDebt, _minimumPoolBadDebt);\\n }\\n\\n /**\\n * @notice Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted\\n * @param _waitForFirstBidder New wait for first bidder block count\\n * @custom:event Emits WaitForFirstBidderUpdated on success\\n * @custom:access Restricted by ACM\\n */\\n function updateWaitForFirstBidder(uint256 _waitForFirstBidder) external {\\n _checkAccessAllowed(\\\"updateWaitForFirstBidder(uint256)\\\");\\n uint256 oldWaitForFirstBidder = waitForFirstBidder;\\n waitForFirstBidder = _waitForFirstBidder;\\n emit WaitForFirstBidderUpdated(oldWaitForFirstBidder, _waitForFirstBidder);\\n }\\n\\n /**\\n * @notice Update the pool registry this shortfall supports\\n * @dev After Pool Registry is deployed we need to set the pool registry address\\n * @param poolRegistry_ Address of pool registry contract\\n * @custom:event Emits PoolRegistryUpdated on success\\n * @custom:access Restricted to owner\\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n */\\n function updatePoolRegistry(address poolRegistry_) external onlyOwner {\\n ensureNonzeroAddress(poolRegistry_);\\n address oldPoolRegistry = poolRegistry;\\n poolRegistry = poolRegistry_;\\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\\n }\\n\\n /**\\n * @notice Pause auctions. This disables starting new auctions but lets the current auction finishes\\n * @custom:event Emits AuctionsPaused on success\\n * @custom:error Errors is auctions are paused\\n * @custom:access Restricted by ACM\\n */\\n function pauseAuctions() external {\\n _checkAccessAllowed(\\\"pauseAuctions()\\\");\\n require(!auctionsPaused, \\\"Auctions are already paused\\\");\\n auctionsPaused = true;\\n emit AuctionsPaused(msg.sender);\\n }\\n\\n /**\\n * @notice Resume paused auctions.\\n * @custom:event Emits AuctionsResumed on success\\n * @custom:error Errors is auctions are active\\n * @custom:access Restricted by ACM\\n */\\n function resumeAuctions() external {\\n _checkAccessAllowed(\\\"resumeAuctions()\\\");\\n require(auctionsPaused, \\\"Auctions are not paused\\\");\\n auctionsPaused = false;\\n emit AuctionsResumed(msg.sender);\\n }\\n\\n /**\\n * @notice Start a auction when there is not currently one active\\n * @param comptroller Comptroller address of the pool\\n */\\n function _startAuction(address comptroller) internal {\\n PoolRegistryInterface.VenusPool memory pool = PoolRegistry(poolRegistry).getPoolByComptroller(comptroller);\\n require(pool.comptroller == comptroller, \\\"comptroller doesn't exist pool registry\\\");\\n\\n Auction storage auction = auctions[comptroller];\\n require(\\n auction.status == AuctionStatus.NOT_STARTED || auction.status == AuctionStatus.ENDED,\\n \\\"auction is on-going\\\"\\n );\\n\\n auction.highestBidBps = 0;\\n auction.highestBidBlock = 0;\\n\\n uint256 marketsCount = auction.markets.length;\\n for (uint256 i; i < marketsCount; ++i) {\\n VToken vToken = auction.markets[i];\\n auction.marketDebt[vToken] = 0;\\n }\\n\\n delete auction.markets;\\n\\n VToken[] memory vTokens = _getAllMarkets(comptroller);\\n marketsCount = vTokens.length;\\n ResilientOracleInterface priceOracle = _getPriceOracle(comptroller);\\n uint256 poolBadDebt;\\n\\n uint256[] memory marketsDebt = new uint256[](marketsCount);\\n auction.markets = new VToken[](marketsCount);\\n\\n for (uint256 i; i < marketsCount; ++i) {\\n uint256 marketBadDebt = vTokens[i].badDebt();\\n\\n priceOracle.updatePrice(address(vTokens[i]));\\n uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / EXP_SCALE;\\n\\n poolBadDebt = poolBadDebt + usdValue;\\n auction.markets[i] = vTokens[i];\\n auction.marketDebt[vTokens[i]] = marketBadDebt;\\n marketsDebt[i] = marketBadDebt;\\n }\\n\\n require(poolBadDebt >= minimumPoolBadDebt, \\\"pool bad debt is too low\\\");\\n\\n priceOracle.updateAssetPrice(riskFund.convertibleBaseAsset());\\n uint256 riskFundBalance = (priceOracle.getPrice(riskFund.convertibleBaseAsset()) *\\n riskFund.getPoolsBaseAssetReserves(comptroller)) / EXP_SCALE;\\n uint256 remainingRiskFundBalance = riskFundBalance;\\n uint256 badDebtPlusIncentive = poolBadDebt + ((poolBadDebt * incentiveBps) / MAX_BPS);\\n if (badDebtPlusIncentive >= riskFundBalance) {\\n auction.startBidBps =\\n (MAX_BPS * MAX_BPS * remainingRiskFundBalance) /\\n (poolBadDebt * (MAX_BPS + incentiveBps));\\n remainingRiskFundBalance = 0;\\n auction.auctionType = AuctionType.LARGE_POOL_DEBT;\\n } else {\\n uint256 maxSeizeableRiskFundBalance = badDebtPlusIncentive;\\n\\n remainingRiskFundBalance = remainingRiskFundBalance - maxSeizeableRiskFundBalance;\\n auction.auctionType = AuctionType.LARGE_RISK_FUND;\\n auction.startBidBps = MAX_BPS;\\n }\\n\\n auction.seizedRiskFund = riskFundBalance - remainingRiskFundBalance;\\n auction.startBlock = block.number;\\n auction.status = AuctionStatus.STARTED;\\n auction.highestBidder = address(0);\\n\\n emit AuctionStarted(\\n comptroller,\\n auction.startBlock,\\n auction.auctionType,\\n auction.markets,\\n marketsDebt,\\n auction.seizedRiskFund,\\n auction.startBidBps\\n );\\n }\\n\\n /**\\n * @dev Returns the price oracle of the pool\\n * @param comptroller Address of the pool's comptroller\\n * @return oracle The pool's price oracle\\n */\\n function _getPriceOracle(address comptroller) internal view returns (ResilientOracleInterface) {\\n return ResilientOracleInterface(ComptrollerViewInterface(comptroller).oracle());\\n }\\n\\n /**\\n * @dev Returns all markets of the pool\\n * @param comptroller Address of the pool's comptroller\\n * @return markets The pool's markets as VToken array\\n */\\n function _getAllMarkets(address comptroller) internal view returns (VToken[] memory) {\\n return ComptrollerInterface(comptroller).getAllMarkets();\\n }\\n\\n /**\\n * @dev Checks if the auction has started\\n * @param auction The auction to query the status for\\n * @return True if the auction has started\\n */\\n function _isStarted(Auction storage auction) internal view returns (bool) {\\n return auction.status == AuctionStatus.STARTED;\\n }\\n\\n /**\\n * @dev Checks if the auction is stale, i.e. there's no bidder and the auction\\n * was started more than waitForFirstBidder blocks ago.\\n * @param auction The auction to query the status for\\n * @return True if the auction is stale\\n */\\n function _isStale(Auction storage auction) internal view returns (bool) {\\n bool noBidder = auction.highestBidder == address(0);\\n return noBidder && (block.number > auction.startBlock + waitForFirstBidder);\\n }\\n}\\n\",\"keccak256\":\"0x7115bf0deaa643edc9d2e79052144f0d6f3fd58c6506888cbfabfca73e9911e4\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { IProtocolShareReserve } from \\\"./RiskFund/IProtocolShareReserve.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n Ownable2StepUpgradeable,\\n AccessControlledV8,\\n VTokenInterface,\\n ExponentialNoError,\\n TokenErrorReporter\\n{\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\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 /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n // Note that the contract is upgradeable. Use initialize() or reinitializers\\n // to set the state variables.\\n _disableInitializers();\\n }\\n\\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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n */\\n function initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) external initializer {\\n ensureNonzeroAddress(admin_);\\n\\n // Initialize the market\\n _initialize(\\n underlying_,\\n comptroller_,\\n interestRateModel_,\\n initialExchangeRateMantissa_,\\n name_,\\n symbol_,\\n decimals_,\\n admin_,\\n accessControlManager_,\\n riskManagement,\\n reserveFactorMantissa_\\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 * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\\n * @return success True if the transfer succeeded, reverts otherwise\\n * @custom:event Emits Transfer event on success\\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n * @custom:access Not restricted\\n */\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external override nonReentrant returns (bool) {\\n _transferTokens(msg.sender, src, dst, amount);\\n return true;\\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 (uint256.max means infinite)\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function approve(address spender, uint256 amount) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n transferAllowances[src][spender] = amount;\\n emit Approval(src, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Increase approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param addedValue The number of additional tokens spender can transfer\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 newAllowance = transferAllowances[src][spender];\\n newAllowance += addedValue;\\n transferAllowances[src][spender] = newAllowance;\\n\\n emit Approval(src, spender, newAllowance);\\n return true;\\n }\\n\\n /**\\n * @notice Decreases approval for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param subtractedValue The number of tokens to remove from total approval\\n * @return success Whether or not the approval succeeded\\n * @custom:event Emits Approval event\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n ensureNonzeroAddress(spender);\\n\\n address src = msg.sender;\\n uint256 currentAllowance = transferAllowances[src][spender];\\n require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n unchecked {\\n currentAllowance -= subtractedValue;\\n }\\n\\n transferAllowances[src][spender] = currentAllowance;\\n\\n emit Approval(src, spender, currentAllowance);\\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 amount The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external override returns (uint256) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return totalBorrows The total borrows with interest\\n */\\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n accrueInterest();\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n return _borrowBalanceStored(account);\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, msg.sender, mintAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param minter User whom the supply will be attributed to\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n * @custom:access Not restricted\\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n */\\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n ensureNonzeroAddress(minter);\\n\\n accrueInterest();\\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n _mintFresh(msg.sender, minter, mintAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, redeemTokens, 0);\\n return NO_ERROR;\\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 receive from redeeming vTokens\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n */\\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\\n _redeemFresh(msg.sender, 0, redeemAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits Borrow event; may emit AccrueInterest\\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n * @custom:access Not restricted\\n */\\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n _borrowFresh(msg.sender, borrowAmount);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n return NO_ERROR;\\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, or type(uint256).max for the full outstanding amount\\n * @return error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n accrueInterest();\\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n return NO_ERROR;\\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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Not restricted\\n */\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external override returns (uint256) {\\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n return NO_ERROR;\\n }\\n\\n /**\\n * @notice sets protocol share accumulated from liquidations\\n * @dev must be equal or less than liquidation incentive - 1\\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n * @custom:event Emits NewProtocolSeizeShare event on success\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n revert ProtocolSeizeShareTooBig();\\n }\\n\\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n accrueInterest();\\n _setReserveFactorFresh(newReserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n * @param reduceAmount Amount of reduction to reserves\\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n * @custom:access Not restricted\\n */\\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n accrueInterest();\\n _reduceReservesFresh(reduceAmount);\\n }\\n\\n /**\\n * @notice The sender adds to reserves.\\n * @param addAmount The amount of underlying token to add as reserves\\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n * @custom:access Not restricted\\n */\\n function addReserves(uint256 addAmount) external override nonReentrant {\\n accrueInterest();\\n _addReservesFresh(addAmount);\\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n * @custom:access Controlled by AccessControlManager\\n */\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n accrueInterest();\\n _setInterestRateModelFresh(newInterestRateModel);\\n }\\n\\n /**\\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n * \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n * may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n * the Comptroller does all the necessary checks before calling this function.\\n * @param payer account who repays the debt\\n * @param borrower account to heal\\n * @param repayAmount amount to repay\\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:access Only Comptroller\\n */\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external override nonReentrant {\\n if (repayAmount != 0) {\\n comptroller.preRepayHook(address(this), borrower);\\n }\\n\\n if (msg.sender != address(comptroller)) {\\n revert HealBorrowUnauthorized();\\n }\\n\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 totalBorrowsNew = totalBorrows;\\n\\n uint256 actualRepayAmount;\\n if (repayAmount != 0) {\\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n actualRepayAmount = _doTransferIn(payer, repayAmount);\\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n emit RepayBorrow(\\n payer,\\n borrower,\\n actualRepayAmount,\\n accountBorrowsPrev - actualRepayAmount,\\n totalBorrowsNew\\n );\\n }\\n\\n // The transaction will fail if trying to repay too much\\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n if (badDebtDelta != 0) {\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld + badDebtDelta;\\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n badDebt = badDebtNew;\\n\\n // We treat healing as \\\"repayment\\\", where vToken is the payer\\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n }\\n\\n accountBorrows[borrower].principal = 0;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n emit HealBorrow(payer, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n * the close factor check. The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n * @custom:access Only Comptroller\\n */\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) external override {\\n if (msg.sender != address(comptroller)) {\\n revert ForceLiquidateBorrowUnauthorized();\\n }\\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\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 * @custom:event Emits Transfer, ReservesAdded events\\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n * @custom:access Not restricted\\n */\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external override nonReentrant {\\n _seize(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Updates bad debt\\n * @dev Called only when bad debt is recovered from auction\\n * @param recoveredAmount_ The amount of bad debt recovered\\n * @custom:event Emits BadDebtRecovered event\\n * @custom:access Only Shortfall contract\\n */\\n function badDebtRecovered(uint256 recoveredAmount_) external {\\n require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n uint256 badDebtOld = badDebt;\\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n badDebt = badDebtNew;\\n\\n emit BadDebtRecovered(badDebtOld, badDebtNew);\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protocolShareReserve_ The address of the protocol share reserve contract\\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n * @custom:access Only Governance\\n */\\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n _setProtocolShareReserve(protocolShareReserve_);\\n }\\n\\n /**\\n * @notice Sets shortfall contract address\\n * @param shortfall_ The address of the shortfall contract\\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n * @custom:access Only Governance\\n */\\n function setShortfallContract(address shortfall_) external onlyOwner {\\n _setShortfallContract(shortfall_);\\n }\\n\\n /**\\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n * @param token The address of the ERC-20 token to sweep\\n * @custom:access Only Governance\\n */\\n function sweepToken(IERC20Upgradeable token) external override {\\n require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n uint256 balance = token.balanceOf(address(this));\\n token.safeTransfer(owner(), balance);\\n\\n emit SweepToken(address(token));\\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n */\\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\\n * @return vTokenBalance User's balance of vTokens\\n * @return borrowBalance Amount owed in terms of underlying\\n * @return exchangeRate Stored exchange rate\\n */\\n function getAccountSnapshot(address account)\\n external\\n view\\n override\\n returns (\\n uint256 error,\\n uint256 vTokenBalance,\\n uint256 borrowBalance,\\n uint256 exchangeRate\\n )\\n {\\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return cash The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view override returns (uint256) {\\n return _getCashPrior();\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return rate The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view override returns (uint256) {\\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this v\\n * @return rate The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view override returns (uint256) {\\n return\\n interestRateModel.getSupplyRate(\\n _getCashPrior(),\\n totalBorrows,\\n totalReserves,\\n reserveFactorMantissa,\\n badDebt\\n );\\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 borrowBalance The calculated balance\\n */\\n function borrowBalanceStored(address account) external view override returns (uint256) {\\n return _borrowBalanceStored(account);\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() external view override returns (uint256) {\\n return _exchangeRateStored();\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n accrueInterest();\\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.\\n * @return Always NO_ERROR\\n * @custom:event Emits AccrueInterest event on success\\n * @custom:access Not restricted\\n */\\n function accrueInterest() public virtual override returns (uint256) {\\n /* Remember the initial block number */\\n uint256 currentBlockNumber = _getBlockNumber();\\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return NO_ERROR;\\n }\\n\\n /* Read the previous values out of storage */\\n uint256 cashPrior = _getCashPrior();\\n uint256 borrowsPrior = totalBorrows;\\n uint256 reservesPrior = totalReserves;\\n uint256 borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\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 NO_ERROR;\\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 payer The address of the account which is sending the assets for supply\\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 */\\n function _mintFresh(\\n address payer,\\n address minter,\\n uint256 mintAmount\\n ) internal {\\n /* Fail if mint not allowed */\\n comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert MintFreshnessCheck();\\n }\\n\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\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 * And write them into storage\\n */\\n totalSupply = totalSupply + mintTokens;\\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n accountTokens[minter] = balanceAfter;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n emit Transfer(address(0), minter, mintTokens);\\n }\\n\\n /**\\n * @notice User redeems vTokens in exchange for the underlying asset\\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 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 */\\n function _redeemFresh(\\n address redeemer,\\n uint256 redeemTokensIn,\\n uint256 redeemAmountIn\\n ) internal {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RedeemFreshnessCheck();\\n }\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n uint256 redeemTokens;\\n uint256 redeemAmount;\\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 */\\n redeemTokens = redeemTokensIn;\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n */\\n redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n }\\n\\n // redeemAmount = exchangeRate * redeemTokens\\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n // Revert if amount is zero\\n if (redeemAmount == 0) {\\n revert(\\\"redeemAmount is zero\\\");\\n }\\n\\n /* Fail if redeem not allowed */\\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (_getCashPrior() - totalReserves < redeemAmount) {\\n revert RedeemTransferOutNotPossible();\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n */\\n totalSupply = totalSupply - redeemTokens;\\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n accountTokens[redeemer] = balanceAfter;\\n\\n /*\\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\\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 _doTransferOut(redeemer, redeemAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), redeemTokens);\\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n }\\n\\n /**\\n * @notice Users borrow assets from the protocol to their own address\\n * @param borrower User who borrows the assets\\n * @param borrowAmount The amount of the underlying asset to borrow\\n */\\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\\n /* Fail if borrow not allowed */\\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert BorrowFreshnessCheck();\\n }\\n\\n /* Fail gracefully if protocol has insufficient underlying cash */\\n if (_getCashPrior() - totalReserves < borrowAmount) {\\n revert BorrowCashNotAvailable();\\n }\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowNew = accountBorrow + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We write the previously calculated values into storage.\\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n `*/\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /*\\n * We invoke _doTransferOut for the borrower and the borrowAmount.\\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(borrower, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n * @return (uint) the actual repayment amount.\\n */\\n function _repayBorrowFresh(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) internal returns (uint256) {\\n /* Fail if repayBorrow not allowed */\\n comptroller.preRepayHook(address(this), borrower);\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert RepayBorrowFreshnessCheck();\\n }\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n return actualRepayAmount;\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal nonReentrant {\\n accrueInterest();\\n\\n uint256 error = vTokenCollateral.accrueInterest();\\n if (error != NO_ERROR) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n revert LiquidateAccrueCollateralInterestFailed(error);\\n }\\n\\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param liquidator The address repaying the borrow and seizing collateral\\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n * regardless of the account liquidity\\n */\\n function _liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipLiquidityCheck\\n ) internal {\\n /* Fail if liquidate not allowed */\\n comptroller.preLiquidateHook(\\n address(this),\\n address(vTokenCollateral),\\n borrower,\\n repayAmount,\\n skipLiquidityCheck\\n );\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert LiquidateFreshnessCheck();\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\\n revert LiquidateCollateralFreshnessCheck();\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateLiquidatorIsBorrower();\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n revert LiquidateCloseAmountIsZero();\\n }\\n\\n /* Fail if repayAmount = type(uint256).max */\\n if (repayAmount == type(uint256).max) {\\n revert LiquidateCloseAmountIsUintMax();\\n }\\n\\n /* Fail if repayBorrow fails */\\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\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.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\\n if (address(vTokenCollateral) == address(this)) {\\n _seize(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\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 */\\n function _seize(\\n address seizerContract,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) internal {\\n /* Fail if seize not allowed */\\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n revert LiquidateSeizeLiquidatorIsBorrower();\\n }\\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n .liquidationIncentiveMantissa();\\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the calculated values into storage */\\n totalReserves = totalReservesNew;\\n totalSupply = totalSupply - protocolSeizeTokens;\\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n emit Transfer(borrower, address(this), protocolSeizeTokens);\\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\\n }\\n\\n function _setComptroller(ComptrollerInterface newComptroller) internal {\\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\\n /**\\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n * @dev Admin function to set a new reserve factor\\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n */\\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetReserveFactorFreshCheck();\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n revert SetReserveFactorBoundsCheck();\\n }\\n\\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\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 actualAddAmount The actual amount added, excluding the potential token fees\\n */\\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n // totalReserves + actualAddAmount\\n uint256 totalReservesNew;\\n uint256 actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert AddReservesFactorFreshCheck(actualAddAmount);\\n }\\n\\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n totalReservesNew = totalReserves + actualAddAmount;\\n totalReserves = totalReservesNew;\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n return actualAddAmount;\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to the protocol reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n */\\n function _reduceReservesFresh(uint256 reduceAmount) internal {\\n // totalReserves - reduceAmount\\n uint256 totalReservesNew;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert ReduceReservesFreshCheck();\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (_getCashPrior() < reduceAmount) {\\n revert ReduceReservesCashNotAvailable();\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n revert ReduceReservesCashValidation();\\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n // Update the pool asset's state in the protocol share reserve for the above transfer.\\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n }\\n\\n /**\\n * @notice updates the interest rate model (*requires fresh interest accrual)\\n * @dev Admin function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != _getBlockNumber()) {\\n revert SetInterestRateModelFreshCheck();\\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\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\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 * @param from Sender of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n * @return Actual amount received\\n */\\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n uint256 balanceBefore = token.balanceOf(address(this));\\n token.safeTransferFrom(from, address(this), amount);\\n uint256 balanceAfter = token.balanceOf(address(this));\\n // Return the amount that was *actually* transferred\\n return balanceAfter - balanceBefore;\\n }\\n\\n /**\\n * @dev Just a regular ERC-20 transfer, reverts on failure\\n * @param to Receiver of the underlying tokens\\n * @param amount Amount of underlying to transfer\\n */\\n function _doTransferOut(address to, uint256 amount) internal virtual {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n token.safeTransfer(to, amount);\\n }\\n\\n /**\\n * @notice Transfer `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 */\\n function _transferTokens(\\n address spender,\\n address src,\\n address dst,\\n uint256 tokens\\n ) internal {\\n /* Fail if transfer not allowed */\\n comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n revert TransferNotAllowed();\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint256 startingAllowance;\\n if (spender == src) {\\n startingAllowance = type(uint256).max;\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n uint256 allowanceNew = startingAllowance - tokens;\\n uint256 srcTokensNew = accountTokens[src] - tokens;\\n uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n\\n accountTokens[src] = srcTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != type(uint256).max) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n }\\n\\n /**\\n * @notice Initialize the 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_ ERC-20 name of this token\\n * @param symbol_ ERC-20 symbol of this token\\n * @param decimals_ ERC-20 decimal precision of this token\\n * @param admin_ Address of the administrator of this token\\n * @param accessControlManager_ AccessControlManager contract address\\n * @param riskManagement Addresses of risk & income related contracts\\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n */\\n function _initialize(\\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 admin_,\\n address accessControlManager_,\\n RiskManagementInit memory riskManagement,\\n uint256 reserveFactorMantissa_\\n ) internal onlyInitializing {\\n __Ownable2Step_init();\\n __AccessControlled_init_unchained(accessControlManager_);\\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 _setComptroller(comptroller_);\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = _getBlockNumber();\\n borrowIndex = MANTISSA_ONE;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n _setInterestRateModelFresh(interestRateModel_);\\n\\n _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n _setShortfallContract(riskManagement.shortfall);\\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n // Set underlying and sanity check it\\n underlying = underlying_;\\n IERC20Upgradeable(underlying).totalSupply();\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n _transferOwnership(admin_);\\n }\\n\\n function _setShortfallContract(address shortfall_) internal {\\n ensureNonzeroAddress(shortfall_);\\n address oldShortfall = shortfall;\\n shortfall = shortfall_;\\n emit NewShortfallContract(oldShortfall, shortfall_);\\n }\\n\\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n ensureNonzeroAddress(protocolShareReserve_);\\n address oldProtocolShareReserve = address(protocolShareReserve);\\n protocolShareReserve = protocolShareReserve_;\\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\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 virtual returns (uint256) {\\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n return token.balanceOf(address(this));\\n }\\n\\n /**\\n * @dev Function to simply retrieve block number\\n * This exists mainly for inheriting test contracts to stub this result.\\n * @return Current block number\\n */\\n function _getBlockNumber() internal view virtual returns (uint256) {\\n return block.number;\\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 borrowBalance the calculated balance\\n */\\n function _borrowBalanceStored(address account) internal view returns (uint256) {\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot memory 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 0;\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n return principalTimesIndex / borrowSnapshot.interestIndex;\\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 exchangeRate Calculated exchange rate scaled by 1e18\\n */\\n function _exchangeRateStored() internal view virtual returns (uint256) {\\n uint256 _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return initialExchangeRateMantissa;\\n }\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n */\\n uint256 totalCash = _getCashPrior();\\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n return exchangeRate;\\n }\\n}\\n\",\"keccak256\":\"0x90ec54cadfdd13bc09a1bc4ae1cc37585b695804a6c95d8b42fb866ec269a300\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\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 uint256 principal;\\n uint256 interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\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 Protocol share Reserve contract address\\n */\\n address payable public protocolShareReserve;\\n\\n // Maximum borrow rate that can ever be applied (.0005% / block)\\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\\n\\n // Maximum fraction of interest that can be set aside for reserves\\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n uint256 internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint256 public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint256 public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint256 public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint256 public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint256 public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint256 public totalSupply;\\n\\n /**\\n * @notice Total bad debt of the market\\n */\\n uint256 public badDebt;\\n\\n // Official record of token balances for each account\\n mapping(address => uint256) internal accountTokens;\\n\\n // Approved token transfer amounts on behalf of others\\n mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n // Mapping of account addresses to outstanding borrow balances\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Share of seized collateral that is added to reserves\\n */\\n uint256 public protocolSeizeShareMantissa;\\n\\n /**\\n * @notice Storage of Shortfall contract address\\n */\\n address public shortfall;\\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[50] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n struct RiskManagementInit {\\n address shortfall;\\n address payable protocolShareReserve;\\n }\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(\\n address indexed payer,\\n address indexed borrower,\\n uint256 repayAmount,\\n uint256 accountBorrows,\\n uint256 totalBorrows\\n );\\n\\n /**\\n * @notice Event emitted when bad debt is accumulated on a market\\n * @param borrower borrower to \\\"forgive\\\"\\n * @param badDebtDelta amount of new bad debt recorded\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when bad debt is recovered via an auction\\n * @param badDebtOld previous bad debt value\\n * @param badDebtNew new bad debt value\\n */\\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address indexed liquidator,\\n address indexed borrower,\\n uint256 repayAmount,\\n address indexed vTokenCollateral,\\n uint256 seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n /**\\n * @notice Event emitted when shortfall contract address is changed\\n */\\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n /**\\n * @notice Event emitted when protocol share reserve contract address is changed\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(\\n InterestRateModel indexed oldInterestRateModel,\\n InterestRateModel indexed newInterestRateModel\\n );\\n\\n /**\\n * @notice Event emitted when protocol seize share is changed\\n */\\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /**\\n * @notice Event emitted when healing the borrow\\n */\\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n /**\\n * @notice Event emitted when tokens are swept\\n */\\n event SweepToken(address indexed token);\\n\\n /*** User Interface ***/\\n\\n function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external virtual returns (uint256);\\n\\n function healBorrow(\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external virtual;\\n\\n function forceLiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral,\\n bool skipCloseFactorCheck\\n ) external virtual;\\n\\n function seize(\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external virtual;\\n\\n function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amount\\n ) external virtual returns (bool);\\n\\n function accrueInterest() external virtual returns (uint256);\\n\\n function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n /*** Admin Functions ***/\\n\\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n function exchangeRateCurrent() external virtual returns (uint256);\\n\\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n function addReserves(uint256 addAmount) external virtual;\\n\\n function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n function balanceOf(address owner) external view virtual returns (uint256);\\n\\n function getAccountSnapshot(address account)\\n external\\n view\\n virtual\\n returns (\\n uint256,\\n uint256,\\n uint256,\\n uint256\\n );\\n\\n function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n function exchangeRateStored() external view virtual returns (uint256);\\n\\n function getCash() external view virtual returns (uint256);\\n\\n /**\\n * @notice Indicator that this is a VToken contract (for inspection)\\n * @return Always true\\n */\\n function isVToken() external pure virtual returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xe82d0de552cfda8da11191a3b0bd24d5e218f182d1fdb776585b97cf27c5f4de\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/TokenDebtTracker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.13;\\n\\nimport { Initializable } from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\n/**\\n * @title TokenDebtTracker\\n * @author Venus\\n * @notice TokenDebtTracker is an abstract contract that handles transfers _out_ of the inheriting contract.\\n * If there is an error transferring out (due to any reason, e.g. the token contract restricted the user from\\n * receiving incoming transfers), the amount is recorded as a debt that can be claimed later.\\n * @dev Note that the inheriting contract keeps some amount of users' tokens on its balance, so be careful when\\n * using balanceOf(address(this))!\\n */\\nabstract contract TokenDebtTracker is Initializable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /**\\n * @notice Mapping (IERC20Upgradeable token => (address user => uint256 amount)).\\n * Tracks failed transfers: when a token transfer fails, we record the\\n * amount of the transfer, so that the user can redeem this debt later.\\n */\\n mapping(IERC20Upgradeable => mapping(address => uint256)) public tokenDebt;\\n\\n /**\\n * @notice Mapping (IERC20Upgradeable token => uint256 amount) shows how many\\n * tokens the contract owes to all users. This is useful for accounting to\\n * understand how much of balanceOf(address(this)) is already owed to users.\\n */\\n mapping(IERC20Upgradeable => uint256) public totalTokenDebt;\\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 * @notice Emitted when the contract's debt to the user is increased due to a failed transfer\\n * @param token Token address\\n * @param user User address\\n * @param amount The amount of debt added\\n */\\n event TokenDebtAdded(address indexed token, address indexed user, uint256 amount);\\n\\n /**\\n * @notice Emitted when a user claims tokens that the contract owes them\\n * @param token Token address\\n * @param user User address\\n * @param amount The amount transferred\\n */\\n event TokenDebtClaimed(address indexed token, address indexed user, uint256 amount);\\n\\n /**\\n * @notice Thrown if the user tries to claim more tokens than they are owed\\n * @param token The token the user is trying to claim\\n * @param owedAmount The amount of tokens the contract owes to the user\\n * @param amount The amount of tokens the user is trying to claim\\n */\\n error InsufficientDebt(address token, address user, uint256 owedAmount, uint256 amount);\\n\\n /**\\n * @notice Thrown if trying to transfer more tokens than the contract currently has\\n * @param token The token the contract is trying to transfer\\n * @param recipient The recipient of the transfer\\n * @param amount The amount of tokens the contract is trying to transfer\\n * @param availableBalance The amount of tokens the contract currently has\\n */\\n error InsufficientBalance(address token, address recipient, uint256 amount, uint256 availableBalance);\\n\\n /**\\n * @notice Transfers the tokens we owe to msg.sender, if any\\n * @param token The token to claim\\n * @param amount_ The amount of tokens to claim (or max uint256 to claim all)\\n * @custom:error InsufficientDebt The contract doesn't have enough debt to the user\\n */\\n function claimTokenDebt(IERC20Upgradeable token, uint256 amount_) external {\\n uint256 owedAmount = tokenDebt[token][msg.sender];\\n uint256 amount = (amount_ == type(uint256).max ? owedAmount : amount_);\\n if (amount > owedAmount) {\\n revert InsufficientDebt(address(token), msg.sender, owedAmount, amount);\\n }\\n unchecked {\\n // Safe because we revert if amount > owedAmount above\\n tokenDebt[token][msg.sender] = owedAmount - amount;\\n }\\n totalTokenDebt[token] -= amount;\\n emit TokenDebtClaimed(address(token), msg.sender, amount);\\n token.safeTransfer(msg.sender, amount);\\n }\\n\\n // solhint-disable-next-line func-name-mixedcase\\n function __TokenDebtTracker_init() internal onlyInitializing {\\n __TokenDebtTracker_init_unchained();\\n }\\n\\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\\n function __TokenDebtTracker_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @dev Transfers tokens to the recipient if the contract has enough balance, or\\n * records the debt if the transfer fails due to reasons unrelated to the contract's\\n * balance (e.g. if the token forbids transfers to the recipient).\\n * @param token The token to transfer\\n * @param to The recipient of the transfer\\n * @param amount The amount to transfer\\n * @custom:error InsufficientBalance The contract doesn't have enough balance to transfer\\n */\\n function _transferOutOrTrackDebt(\\n IERC20Upgradeable token,\\n address to,\\n uint256 amount\\n ) internal {\\n uint256 balance = token.balanceOf(address(this));\\n if (balance < amount) {\\n revert InsufficientBalance(address(token), address(this), amount, balance);\\n }\\n _transferOutOrTrackDebtSkippingBalanceCheck(token, to, amount);\\n }\\n\\n /**\\n * @dev Transfers tokens to the recipient, or records the debt if the transfer fails\\n * due to any reason, including insufficient balance.\\n * @param token The token to transfer\\n * @param to The recipient of the transfer\\n * @param amount The amount to transfer\\n */\\n function _transferOutOrTrackDebtSkippingBalanceCheck(\\n IERC20Upgradeable token,\\n address to,\\n uint256 amount\\n ) internal {\\n // We can't use safeTransfer here because we can't try-catch internal calls\\n bool success = _tryTransferOut(token, to, amount);\\n if (!success) {\\n tokenDebt[token][to] += amount;\\n totalTokenDebt[token] += amount;\\n emit TokenDebtAdded(address(token), to, amount);\\n }\\n }\\n\\n /**\\n * @dev Either transfers tokens to the recepient or returns false. Supports tokens\\n * thet revert or return false to indicate failure, and the non-compliant ones\\n * that do not return any value.\\n * @param token The token to transfer\\n * @param to The recipient of the transfer\\n * @param amount The amount to transfer\\n * @return true if the transfer succeeded, false otherwise\\n */\\n function _tryTransferOut(\\n IERC20Upgradeable token,\\n address to,\\n uint256 amount\\n ) private returns (bool) {\\n bytes memory callData = abi.encodeCall(token.transfer, (to, amount));\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(callData);\\n return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\\n }\\n}\\n\",\"keccak256\":\"0xa6fdbe421f8644f481706f22e9f52d72425d62c22bc036d00d46d6dbc61d3776\",\"license\":\"MIT\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x04cd899695ea593a2529cb6a1a04c2a34bff0c1516bd70a5f638ae7a850cad8b\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.13;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0x909eb76841ebd57d8f53686b76b1a09da7bbbbcddb29510c41674d5aa84c713e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61379080620000f36000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c806376ee801711610104578063a23926e1116100a2578063c350a1b511610071578063c350a1b51461043a578063e30c39781461044d578063e630fee01461045e578063f2fde38b1461047157600080fd5b8063a23926e1146103e4578063ae8ddcb014610402578063afcff50f14610415578063b4a0bdf31461042957600080fd5b80637f9c714f116100de5780637f9c714f14610396578063892149a3146103c15780638da5cb5b146103cb57806391f8e694146103dc57600080fd5b806376ee80171461034f57806379ba5097146103625780637cf890301461036a57600080fd5b80634b34e5661161017c578063690d6a141161014b578063690d6a141461030a5780636f254c321461032a578063715018a61461033d57806373d73f401461034557600080fd5b80634b34e566146102c957806351b2fd01146102dc5780635be3fe1b146102ef57806367cd03ab146102f757600080fd5b80631d59410a116101b85780631d59410a1461021a578063264ad3d4146102945780634075fa0f146102ac578063438d33d7146102bf57600080fd5b806304717aca146101df5780630db011d0146101f45780630e32cb8614610207575b600080fd5b6101f26101ed366004612fcf565b610484565b005b6101f2610202366004613004565b610afb565b6101f2610215366004613004565b610c60565b610277610228366004613004565b610134602052600090815260409020805460018201546003830154600484015460058501546006860154600790960154949560ff8086169661010090960416946001600160a01b039093169288565b60405161028b98979695949392919061304b565b60405180910390f35b61029e61012f5481565b60405190815260200161028b565b6101f26102ba366004613004565b610c71565b61029e6101305481565b6101f26102d7366004613004565b610cd6565b6101f26102ea3660046130aa565b611300565b6101f2611368565b6101f26103053660046130aa565b61142d565b61029e610318366004613004565b60fc6020526000908152604090205481565b6101f26103383660046130aa565b6114fa565b6101f26115b6565b61029e6101315481565b6101f261035d3660046130c3565b6115ca565b6101f26116e3565b61012e5461037e906001600160a01b031681565b6040516001600160a01b03909116815260200161028b565b61029e6103a43660046130ef565b60fb60209081526000928352604080842090915290825290205481565b61029e6101335481565b6033546001600160a01b031661037e565b6101f261175a565b610132546103f29060ff1681565b604051901515815260200161028b565b6101f2610410366004613004565b61181c565b61012d5461037e906001600160a01b031681565b6097546001600160a01b031661037e565b6101f2610448366004613128565b611880565b6065546001600160a01b031661037e565b6101f261046c3660046130aa565b611a45565b6101f261047f366004613004565b611aa5565b61048c611b16565b6001600160a01b038316600090815261013460205260409020805482146104fa5760405162461bcd60e51b815260206004820152601a60248201527f61756374696f6e20686173206265656e2072657374617274656400000000000060448201526064015b60405180910390fd5b61050381611b6f565b61051f5760405162461bcd60e51b81526004016104f19061316a565b61052881611b97565b156105755760405162461bcd60e51b815260206004820152601c60248201527f61756374696f6e206973207374616c652c20726573746172742069740000000060448201526064016104f1565b600083116105c55760405162461bcd60e51b815260206004820152601b60248201527f626173697320706f696e74732063616e6e6f74206265207a65726f000000000060448201526064016104f1565b6127108311156106265760405162461bcd60e51b815260206004820152602660248201527f626173697320706f696e74732063616e6e6f74206265206d6f7265207468616e60448201526502031303030360d41b60648201526084016104f1565b600060018083015460ff169081111561064157610641613021565b14801561068d575060048101546001600160a01b0316158015906106685750806005015483115b8061068d575060048101546001600160a01b031615801561068d575080600701548310155b806106f8575060018181015460ff16818111156106ac576106ac613021565b1480156106f8575060048101546001600160a01b0316158015906106d35750806005015483105b806106f8575060048101546001600160a01b03161580156106f8575080600701548311155b6107445760405162461bcd60e51b815260206004820152601b60248201527f796f757220626964206973206e6f74207468652068696768657374000000000060448201526064016104f1565b600281015460005b81811015610a7f57600083600201828154811061076b5761076b613197565b600091825260208083209091015460408051636f307dc360e01b815290516001600160a01b0390921694508492636f307dc3926004808401938290030181865afa1580156107bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e191906131bd565b60048601549091506001600160a01b03161561085857610858818660040160009054906101000a90046001600160a01b031687600901600089600201888154811061082e5761082e613197565b60009182526020808320909101546001600160a01b03168352820192909252604001902054611bcb565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561089f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c391906131da565b9050600060018088015460ff16908111156108e0576108e0613021565b0361095c576000612710898860080160008a600201898154811061090657610906613197565b60009182526020808320909101546001600160a01b031683528201929092526040019020546109359190613209565b61093f9190613228565b90506109566001600160a01b038416333084611c83565b506109b1565b6109b133308860080160008a600201898154811061097c5761097c613197565b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902054908616929190611c83565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156109f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1c91906131da565b9050610a28828261324a565b876009016000896002018881548110610a4357610a43613197565b60009182526020808320909101546001600160a01b0316835282019290925260400190205550610a7892508391506132619050565b905061074c565b506004820180546001600160a01b0319163390811790915560058301859055436006840155825460408051918252602082018790526001600160a01b038816917f5485cf82060404805b51f48c0c4afa3cec4a9e5755c0131e1243553f0eebb9a3910160405180910390a35050610af6600160c955565b505050565b610b03611b16565b6001600160a01b0381166000908152610134602052604090206101325460ff1615610b665760405162461bcd60e51b8152602060048201526013602482015272185d58dd1a5bdb9cc8185c99481c185d5cd959606a1b60448201526064016104f1565b610b6f81611b6f565b610b8b5760405162461bcd60e51b81526004016104f19061316a565b610b9481611b97565b610bf85760405162461bcd60e51b815260206004820152602f60248201527f796f75206e65656420746f207761697420666f72206d6f72652074696d65206660448201526e37b9103334b939ba103134b23232b960891b60648201526084016104f1565b60018101805461ff001916610200179055805460408051918252516001600160a01b038416917faca104a4f0d6f116782afaefa8b644e86d53857ff9151824131b726b49a858d4919081900360200190a2610c5282611cf5565b50610c5d600160c955565b50565b610c68612694565b610c5d816126ee565b610c79611b16565b6101325460ff1615610cc35760405162461bcd60e51b8152602060048201526013602482015272105d58dd1a5bdb9cc8185c99481c185d5cd959606a1b60448201526064016104f1565b610ccc81611cf5565b610c5d600160c955565b610cde611b16565b6001600160a01b038116600090815261013460205260409020610d0081611b6f565b610d1c5760405162461bcd60e51b81526004016104f19061316a565b610131548160060154610d2f919061327a565b43118015610d49575060048101546001600160a01b031615155b610dab5760405162461bcd60e51b815260206004820152602d60248201527f77616974696e6720666f72206e657874206269646465722e2063616e6e6f742060448201526c31b637b9b29030bab1ba34b7b760991b60648201526084016104f1565b600281015460008167ffffffffffffffff811115610dcb57610dcb613292565b604051908082528060200260200182016040528015610df4578160200160208202803683370190505b5060018401805461ff001916610200179055905060005b8281101561113b576000846002018281548110610e2a57610e2a613197565b600091825260208083209091015460408051636f307dc360e01b815290516001600160a01b0390921694508492636f307dc3926004808401938290030181865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea091906131bd565b90506000816001600160a01b03166370a08231886002018681548110610ec857610ec8613197565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015610f18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3c91906131da565b9050610fc3876002018581548110610f5657610f56613197565b9060005260206000200160009054906101000a90046001600160a01b03168860090160008a6002018881548110610f8f57610f8f613197565b60009182526020808320909101546001600160a01b03908116845290830193909352604090910190205490851691906127ac565b6000826001600160a01b03166370a08231896002018781548110610fe957610fe9613197565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015611039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105d91906131da565b9050611069828261324a565b86868151811061107b5761107b613197565b60200260200101818152505087600201858154811061109c5761109c613197565b60009182526020909120015486516001600160a01b039091169063ef60450c908890889081106110ce576110ce613197565b60200260200101516040518263ffffffff1660e01b81526004016110f491815260200190565b600060405180830381600087803b15801561110e57600080fd5b505af1158015611122573d6000803e3d6000fd5b50505050505050508061113490613261565b9050610e0b565b5060008060018086015460ff169081111561115857611158613021565b036111685750600383015461118c565b6127108460050154856003015461117f9190613209565b6111899190613228565b90505b61012e546040805163c8ecc0d360e01b815290516000926001600160a01b03169163c8ecc0d39160048083019260209291908290030181865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb91906131bd565b61012e54604051630a9837c560e01b81526001600160a01b0389811660048301526024820186905292935060009290911690630a9837c5906044016020604051808303816000875af1158015611255573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127991906131da565b60048701549091506112969083906001600160a01b031685611bcb565b6004860154865460058801546040516001600160a01b03938416938b16927ff50338be3ffa7cdbebca76c758cfd1745fb4abe5bd3736c2dbf0cc6483a7b93f926112e892879060028e01908c90613321565b60405180910390a3505050505050610c5d600160c955565b6113216040518060600160405280602181526020016136f6602191396127dc565b61012f80549082905560408051828152602081018490527f85814f0246fcd999c88af70c9e6238211e79444ff07ec745b80aed19ddb268c891015b60405180910390a15050565b6113996040518060400160405280601081526020016f726573756d6541756374696f6e73282960801b8152506127dc565b6101325460ff166113ec5760405162461bcd60e51b815260206004820152601760248201527f41756374696f6e7320617265206e6f742070617573656400000000000000000060448201526064016104f1565b610132805460ff191690556040513381527f91b812e075fb9190eebe2d938c00a7179d150156469a467ec60a290035f4635a906020015b60405180910390a1565b61146b6040518060400160405280601b81526020017f757064617465496e63656e746976654270732875696e743235362900000000008152506127dc565b806000036114bb5760405162461bcd60e51b815260206004820152601a60248201527f696e63656e74697665427073206d757374206e6f74206265203000000000000060448201526064016104f1565b61013080549082905560408051828152602081018490527f3d438fa36c5052935d12a6925d1660c8150c74ef11ca672d4279bc6fd41b8bcf910161135c565b61151b604051806060016040528060238152602001613717602391396127dc565b806000036115775760405162461bcd60e51b815260206004820152602360248201527f5f6e657874426964646572426c6f636b4c696d6974206d757374206e6f74206260448201526206520360ec1b60648201526084016104f1565b61013180549082905560408051828152602081018490527f3f22dba09ee9845bd2be6926fea5337a0db935ca059cbb205d62174783e29664910161135c565b6115be612694565b6115c8600061287a565b565b6001600160a01b038216600090815260fb602090815260408083203384529091528120549060001983146115fe5782611600565b815b90508181111561164257604051639d2df25760e01b81526001600160a01b038516600482015233602482015260448101839052606481018290526084016104f1565b6001600160a01b038416600081815260fb602090815260408083203384528252808320858703905592825260fc9052908120805483929061168490849061324a565b909155505060405181815233906001600160a01b038616907f8d0aa4a41b0206123877a3705f51d17acf5f31dc241d24188abb2b881297ecfd9060200160405180910390a36116dd6001600160a01b03851633836127ac565b50505050565b60655433906001600160a01b031681146117515760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016104f1565b610c5d8161287a565b61178a6040518060400160405280600f81526020016e706175736541756374696f6e73282960881b8152506127dc565b6101325460ff16156117de5760405162461bcd60e51b815260206004820152601b60248201527f41756374696f6e732061726520616c726561647920706175736564000000000060448201526064016104f1565b610132805460ff191660011790556040513381527fc1be5163c9ebecf05bfbd6c6ae7c2b6ce2d3c43088dffaf5270cbf951615049990602001611423565b611824612694565b61182d81612893565b61012d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b600054610100900460ff16158080156118a05750600054600160ff909116105b806118ba5750303b1580156118ba575060005460ff166001145b61191d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104f1565b6000805460ff191660011790558015611940576000805461ff0019166101001790555b61194984612893565b826000036119995760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964206d696e696d756d20706f6f6c20626164206465627400000060448201526064016104f1565b6119a16128ba565b6119aa826128e9565b6119b2612910565b6119ba61293f565b61012f83905561012e80546001600160a01b0319166001600160a01b0386161790556064610133819055610131556103e861013055610132805460ff1916905580156116dd576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b611a6660405180606001604052806021815260200161373a602191396127dc565b61013380549082905560408051828152602081018490527f2a5be8a6b827e16c392d22522295794d6baff64565057a17b1f14c9d6c125a60910161135c565b611aad612694565b606580546001600160a01b0383166001600160a01b03199091168117909155611ade6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600260c95403611b685760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f1565b600260c955565b6000600180830154610100900460ff166002811115611b9057611b90613021565b1492915050565b60048101546000906001600160a01b031615808015611bc45750610133548354611bc1919061327a565b43115b9392505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015611c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3691906131da565b905081811015611c785760405163861da4bd60e01b81526001600160a01b038516600482015230602482015260448101839052606481018290526084016104f1565b6116dd84848461296e565b6040516001600160a01b03808516602483015283166044820152606481018290526116dd9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a40565b600160c955565b61012d54604051637aee632d60e01b81526001600160a01b0383811660048301526000921690637aee632d90602401600060405180830381865afa158015611d41573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d6991908101906133ea565b9050816001600160a01b031681604001516001600160a01b031614611de05760405162461bcd60e51b815260206004820152602760248201527f636f6d7074726f6c6c657220646f65736e277420657869737420706f6f6c20726044820152666567697374727960c81b60648201526084016104f1565b6001600160a01b038216600090815261013460205260408120906001820154610100900460ff166002811115611e1857611e18613021565b1480611e41575060026001820154610100900460ff166002811115611e3f57611e3f613021565b145b611e835760405162461bcd60e51b815260206004820152601360248201527261756374696f6e206973206f6e2d676f696e6760681b60448201526064016104f1565b600060058201819055600682018190556002820154905b81811015611eee576000836002018281548110611eb957611eb9613197565b60009182526020808320909101546001600160a01b03168252600886019052604081205550611ee781613261565b9050611e9a565b50611efd600283016000612f22565b6000611f0885612b15565b9050805191506000611f1986612b83565b90506000808467ffffffffffffffff811115611f3757611f37613292565b604051908082528060200260200182016040528015611f60578160200160208202803683370190505b5090508467ffffffffffffffff811115611f7c57611f7c613292565b604051908082528060200260200182016040528015611fa5578160200160208202803683370190505b508051611fbc916002890191602090910190612f40565b5060005b85811015612264576000858281518110611fdc57611fdc613197565b60200260200101516001600160a01b031663bbcac5576040518163ffffffff1660e01b8152600401602060405180830381865afa158015612021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204591906131da565b9050846001600160a01b03166396e85ced87848151811061206857612068613197565b60200260200101516040518263ffffffff1660e01b815260040161209b91906001600160a01b0391909116815260200190565b600060405180830381600087803b1580156120b557600080fd5b505af11580156120c9573d6000803e3d6000fd5b505050506000670de0b6b3a764000082876001600160a01b031663fc57d4df8a87815181106120fa576120fa613197565b60200260200101516040518263ffffffff1660e01b815260040161212d91906001600160a01b0391909116815260200190565b602060405180830381865afa15801561214a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216e91906131da565b6121789190613209565b6121829190613228565b905061218e818661327a565b94508683815181106121a2576121a2613197565b60200260200101518960020184815481106121bf576121bf613197565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508189600801600089868151811061220657612206613197565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508184848151811061224557612245613197565b60200260200101818152505050508061225d90613261565b9050611fc0565b5061012f548210156122b85760405162461bcd60e51b815260206004820152601860248201527f706f6f6c20626164206465627420697320746f6f206c6f77000000000000000060448201526064016104f1565b826001600160a01b031663b62cad6961012e60009054906101000a90046001600160a01b03166001600160a01b031663c8ecc0d36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561231b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233f91906131bd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b15801561238057600080fd5b505af1158015612394573d6000803e3d6000fd5b505061012e5460405163534de8cf60e11b81526001600160a01b038c8116600483015260009450670de0b6b3a764000093509091169063a69bd19e90602401602060405180830381865afa1580156123f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241491906131da565b856001600160a01b03166341976e0961012e60009054906101000a90046001600160a01b03166001600160a01b031663c8ecc0d36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249b91906131bd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156124df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250391906131da565b61250d9190613209565b6125179190613228565b90506000819050600061271061013054866125329190613209565b61253c9190613228565b612546908661327a565b90508281106125a4576101305461255f9061271061327a565b6125699086613209565b8261257661271080613209565b6125809190613209565b61258a9190613228565b60078a015560018901805460ff19169055600091506125cb565b806125af818461324a565b60018b8101805460ff1916909117905561271060078c01559250505b6125d5828461324a565b60038a01554389556001808a01805461ff00191661010083021790555060008960040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6001600160a01b03167f56c1f0c5ea96c78d614c0246b1915086a325f09ce15526bd5d69b50232d681328a600001548b60010160009054906101000a900460ff168c600201888e600301548f6007015460405161267f969594939291906134e0565b60405180910390a25050505050505050505050565b6033546001600160a01b031633146115c85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f1565b6001600160a01b0381166127525760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b60648201526084016104f1565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0910161135c565b6040516001600160a01b038316602482015260448101829052610af690849063a9059cbb60e01b90606401611cb7565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab9061280f903390869060040161355a565b602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612850919061357e565b90508061287657333083604051634a3fa29360e01b81526004016104f1939291906135a0565b5050565b606580546001600160a01b0319169055610c5d81612be7565b6001600160a01b038116610c5d576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff166128e15760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c39565b600054610100900460ff16610c685760405162461bcd60e51b81526004016104f1906135d5565b600054610100900460ff166129375760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c69565b600054610100900460ff166129665760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c90565b600061297b848484612cb7565b9050806116dd576001600160a01b03808516600090815260fb60209081526040808320938716835292905290812080548492906129b990849061327a565b90915550506001600160a01b038416600090815260fc6020526040812080548492906129e690849061327a565b92505081905550826001600160a01b0316846001600160a01b03167fca6abeb3233ce8fb0de841c83102849b2d4165b80c92c5627899a5148ab4650084604051612a3291815260200190565b60405180910390a350505050565b6000612a95826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612da29092919063ffffffff16565b9050805160001480612ab6575080806020019051810190612ab6919061357e565b610af65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016104f1565b6060816001600160a01b031663b0772d0b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015612b55573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b7d9190810190613620565b92915050565b6000816001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7d91906131bd565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16612c605760405162461bcd60e51b81526004016104f1906135d5565b6115c83361287a565b600054610100900460ff16611cee5760405162461bcd60e51b81526004016104f1906135d5565b600054610100900460ff166115c85760405162461bcd60e51b81526004016104f1906135d5565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283918291881690612d159085906136c6565b6000604051808303816000865af19150503d8060008114612d52576040519150601f19603f3d011682016040523d82523d6000602084013e612d57565b606091505b5091509150818015612d81575080511580612d81575080806020019051810190612d81919061357e565b8015612d9757506000876001600160a01b03163b115b979650505050505050565b6060612db18484600085612db9565b949350505050565b606082471015612e1a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016104f1565b600080866001600160a01b03168587604051612e3691906136c6565b60006040518083038185875af1925050503d8060008114612e73576040519150601f19603f3d011682016040523d82523d6000602084013e612e78565b606091505b5091509150612d978783838760608315612ef3578251600003612eec576001600160a01b0385163b612eec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f1565b5081612db1565b612db18383815115612f085781518083602001fd5b8060405162461bcd60e51b81526004016104f191906136e2565b5080546000825590600052602060002090810190610c5d9190612fa5565b828054828255906000526020600020908101928215612f95579160200282015b82811115612f9557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612f60565b50612fa1929150612fa5565b5090565b5b80821115612fa15760008155600101612fa6565b6001600160a01b0381168114610c5d57600080fd5b600080600060608486031215612fe457600080fd5b8335612fef81612fba565b95602085013595506040909401359392505050565b60006020828403121561301657600080fd5b8135611bc481612fba565b634e487b7160e01b600052602160045260246000fd5b6002811061304757613047613021565b9052565b8881526101008101613060602083018a613037565b6003881061307057613070613021565b604082019790975260608101959095526001600160a01b0393909316608085015260a084019190915260c083015260e09091015292915050565b6000602082840312156130bc57600080fd5b5035919050565b600080604083850312156130d657600080fd5b82356130e181612fba565b946020939093013593505050565b6000806040838503121561310257600080fd5b823561310d81612fba565b9150602083013561311d81612fba565b809150509250929050565b60008060006060848603121561313d57600080fd5b833561314881612fba565b925060208401359150604084013561315f81612fba565b809150509250925092565b60208082526013908201527237379037b716b3b7b4b7339030bab1ba34b7b760691b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b80516131b881612fba565b919050565b6000602082840312156131cf57600080fd5b8151611bc481612fba565b6000602082840312156131ec57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613223576132236131f3565b500290565b60008261324557634e487b7160e01b600052601260045260246000fd5b500490565b60008282101561325c5761325c6131f3565b500390565b600060018201613273576132736131f3565b5060010190565b6000821982111561328d5761328d6131f3565b500190565b634e487b7160e01b600052604160045260246000fd5b6000815480845260208085019450836000528060002060005b838110156132e65781546001600160a01b0316875295820195600191820191016132c1565b509495945050505050565b600081518084526020808501945080840160005b838110156132e657815187529582019590820190600101613305565b85815284602082015283604082015260a06060820152600061334660a08301856132a8565b828103608084015261335881856132f1565b98975050505050505050565b60405160a0810167ffffffffffffffff8111828210171561338757613387613292565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156133b6576133b6613292565b604052919050565b60005b838110156133d95781810151838201526020016133c1565b838111156116dd5750506000910152565b600060208083850312156133fd57600080fd5b825167ffffffffffffffff8082111561341557600080fd5b9084019060a0828703121561342957600080fd5b613431613364565b82518281111561344057600080fd5b8301601f8101881361345157600080fd5b80518381111561346357613463613292565b613475601f8201601f1916870161338d565b9350808452888682840101111561348b57600080fd5b61349a818786018885016133be565b50508181526134aa8484016131ad565b848201526134ba604084016131ad565b604082015260608301516060820152608083015160808201528094505050505092915050565b8681526134f06020820187613037565b60c06040820152600061350660c08301876132a8565b828103606084015261351881876132f1565b6080840195909552505060a00152949350505050565b600081518084526135468160208601602086016133be565b601f01601f19169290920160200192915050565b6001600160a01b0383168152604060208201819052600090612db19083018461352e565b60006020828403121561359057600080fd5b81518015158114611bc457600080fd5b6001600160a01b038481168252831660208201526060604082018190526000906135cc9083018461352e565b95945050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6000602080838503121561363357600080fd5b825167ffffffffffffffff8082111561364b57600080fd5b818501915085601f83011261365f57600080fd5b81518181111561367157613671613292565b8060051b915061368284830161338d565b818152918301840191848101908884111561369c57600080fd5b938501935b8385101561335857845192506136b683612fba565b82825293850193908501906136a1565b600082516136d88184602087016133be565b9190910192915050565b602081526000611bc4602083018461352e56fe7570646174654d696e696d756d506f6f6c426164446562742875696e74323536297570646174654e657874426964646572426c6f636b4c696d69742875696e743235362975706461746557616974466f7246697273744269646465722875696e7432353629a2646970667358221220cdd1210a9ea7d2dc0776d5d22df850b673565d10413487e9a45d7df9c7039cdf64736f6c634300080d0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101da5760003560e01c806376ee801711610104578063a23926e1116100a2578063c350a1b511610071578063c350a1b51461043a578063e30c39781461044d578063e630fee01461045e578063f2fde38b1461047157600080fd5b8063a23926e1146103e4578063ae8ddcb014610402578063afcff50f14610415578063b4a0bdf31461042957600080fd5b80637f9c714f116100de5780637f9c714f14610396578063892149a3146103c15780638da5cb5b146103cb57806391f8e694146103dc57600080fd5b806376ee80171461034f57806379ba5097146103625780637cf890301461036a57600080fd5b80634b34e5661161017c578063690d6a141161014b578063690d6a141461030a5780636f254c321461032a578063715018a61461033d57806373d73f401461034557600080fd5b80634b34e566146102c957806351b2fd01146102dc5780635be3fe1b146102ef57806367cd03ab146102f757600080fd5b80631d59410a116101b85780631d59410a1461021a578063264ad3d4146102945780634075fa0f146102ac578063438d33d7146102bf57600080fd5b806304717aca146101df5780630db011d0146101f45780630e32cb8614610207575b600080fd5b6101f26101ed366004612fcf565b610484565b005b6101f2610202366004613004565b610afb565b6101f2610215366004613004565b610c60565b610277610228366004613004565b610134602052600090815260409020805460018201546003830154600484015460058501546006860154600790960154949560ff8086169661010090960416946001600160a01b039093169288565b60405161028b98979695949392919061304b565b60405180910390f35b61029e61012f5481565b60405190815260200161028b565b6101f26102ba366004613004565b610c71565b61029e6101305481565b6101f26102d7366004613004565b610cd6565b6101f26102ea3660046130aa565b611300565b6101f2611368565b6101f26103053660046130aa565b61142d565b61029e610318366004613004565b60fc6020526000908152604090205481565b6101f26103383660046130aa565b6114fa565b6101f26115b6565b61029e6101315481565b6101f261035d3660046130c3565b6115ca565b6101f26116e3565b61012e5461037e906001600160a01b031681565b6040516001600160a01b03909116815260200161028b565b61029e6103a43660046130ef565b60fb60209081526000928352604080842090915290825290205481565b61029e6101335481565b6033546001600160a01b031661037e565b6101f261175a565b610132546103f29060ff1681565b604051901515815260200161028b565b6101f2610410366004613004565b61181c565b61012d5461037e906001600160a01b031681565b6097546001600160a01b031661037e565b6101f2610448366004613128565b611880565b6065546001600160a01b031661037e565b6101f261046c3660046130aa565b611a45565b6101f261047f366004613004565b611aa5565b61048c611b16565b6001600160a01b038316600090815261013460205260409020805482146104fa5760405162461bcd60e51b815260206004820152601a60248201527f61756374696f6e20686173206265656e2072657374617274656400000000000060448201526064015b60405180910390fd5b61050381611b6f565b61051f5760405162461bcd60e51b81526004016104f19061316a565b61052881611b97565b156105755760405162461bcd60e51b815260206004820152601c60248201527f61756374696f6e206973207374616c652c20726573746172742069740000000060448201526064016104f1565b600083116105c55760405162461bcd60e51b815260206004820152601b60248201527f626173697320706f696e74732063616e6e6f74206265207a65726f000000000060448201526064016104f1565b6127108311156106265760405162461bcd60e51b815260206004820152602660248201527f626173697320706f696e74732063616e6e6f74206265206d6f7265207468616e60448201526502031303030360d41b60648201526084016104f1565b600060018083015460ff169081111561064157610641613021565b14801561068d575060048101546001600160a01b0316158015906106685750806005015483115b8061068d575060048101546001600160a01b031615801561068d575080600701548310155b806106f8575060018181015460ff16818111156106ac576106ac613021565b1480156106f8575060048101546001600160a01b0316158015906106d35750806005015483105b806106f8575060048101546001600160a01b03161580156106f8575080600701548311155b6107445760405162461bcd60e51b815260206004820152601b60248201527f796f757220626964206973206e6f74207468652068696768657374000000000060448201526064016104f1565b600281015460005b81811015610a7f57600083600201828154811061076b5761076b613197565b600091825260208083209091015460408051636f307dc360e01b815290516001600160a01b0390921694508492636f307dc3926004808401938290030181865afa1580156107bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e191906131bd565b60048601549091506001600160a01b03161561085857610858818660040160009054906101000a90046001600160a01b031687600901600089600201888154811061082e5761082e613197565b60009182526020808320909101546001600160a01b03168352820192909252604001902054611bcb565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561089f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c391906131da565b9050600060018088015460ff16908111156108e0576108e0613021565b0361095c576000612710898860080160008a600201898154811061090657610906613197565b60009182526020808320909101546001600160a01b031683528201929092526040019020546109359190613209565b61093f9190613228565b90506109566001600160a01b038416333084611c83565b506109b1565b6109b133308860080160008a600201898154811061097c5761097c613197565b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902054908616929190611c83565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156109f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1c91906131da565b9050610a28828261324a565b876009016000896002018881548110610a4357610a43613197565b60009182526020808320909101546001600160a01b0316835282019290925260400190205550610a7892508391506132619050565b905061074c565b506004820180546001600160a01b0319163390811790915560058301859055436006840155825460408051918252602082018790526001600160a01b038816917f5485cf82060404805b51f48c0c4afa3cec4a9e5755c0131e1243553f0eebb9a3910160405180910390a35050610af6600160c955565b505050565b610b03611b16565b6001600160a01b0381166000908152610134602052604090206101325460ff1615610b665760405162461bcd60e51b8152602060048201526013602482015272185d58dd1a5bdb9cc8185c99481c185d5cd959606a1b60448201526064016104f1565b610b6f81611b6f565b610b8b5760405162461bcd60e51b81526004016104f19061316a565b610b9481611b97565b610bf85760405162461bcd60e51b815260206004820152602f60248201527f796f75206e65656420746f207761697420666f72206d6f72652074696d65206660448201526e37b9103334b939ba103134b23232b960891b60648201526084016104f1565b60018101805461ff001916610200179055805460408051918252516001600160a01b038416917faca104a4f0d6f116782afaefa8b644e86d53857ff9151824131b726b49a858d4919081900360200190a2610c5282611cf5565b50610c5d600160c955565b50565b610c68612694565b610c5d816126ee565b610c79611b16565b6101325460ff1615610cc35760405162461bcd60e51b8152602060048201526013602482015272105d58dd1a5bdb9cc8185c99481c185d5cd959606a1b60448201526064016104f1565b610ccc81611cf5565b610c5d600160c955565b610cde611b16565b6001600160a01b038116600090815261013460205260409020610d0081611b6f565b610d1c5760405162461bcd60e51b81526004016104f19061316a565b610131548160060154610d2f919061327a565b43118015610d49575060048101546001600160a01b031615155b610dab5760405162461bcd60e51b815260206004820152602d60248201527f77616974696e6720666f72206e657874206269646465722e2063616e6e6f742060448201526c31b637b9b29030bab1ba34b7b760991b60648201526084016104f1565b600281015460008167ffffffffffffffff811115610dcb57610dcb613292565b604051908082528060200260200182016040528015610df4578160200160208202803683370190505b5060018401805461ff001916610200179055905060005b8281101561113b576000846002018281548110610e2a57610e2a613197565b600091825260208083209091015460408051636f307dc360e01b815290516001600160a01b0390921694508492636f307dc3926004808401938290030181865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea091906131bd565b90506000816001600160a01b03166370a08231886002018681548110610ec857610ec8613197565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015610f18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3c91906131da565b9050610fc3876002018581548110610f5657610f56613197565b9060005260206000200160009054906101000a90046001600160a01b03168860090160008a6002018881548110610f8f57610f8f613197565b60009182526020808320909101546001600160a01b03908116845290830193909352604090910190205490851691906127ac565b6000826001600160a01b03166370a08231896002018781548110610fe957610fe9613197565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015611039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105d91906131da565b9050611069828261324a565b86868151811061107b5761107b613197565b60200260200101818152505087600201858154811061109c5761109c613197565b60009182526020909120015486516001600160a01b039091169063ef60450c908890889081106110ce576110ce613197565b60200260200101516040518263ffffffff1660e01b81526004016110f491815260200190565b600060405180830381600087803b15801561110e57600080fd5b505af1158015611122573d6000803e3d6000fd5b50505050505050508061113490613261565b9050610e0b565b5060008060018086015460ff169081111561115857611158613021565b036111685750600383015461118c565b6127108460050154856003015461117f9190613209565b6111899190613228565b90505b61012e546040805163c8ecc0d360e01b815290516000926001600160a01b03169163c8ecc0d39160048083019260209291908290030181865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb91906131bd565b61012e54604051630a9837c560e01b81526001600160a01b0389811660048301526024820186905292935060009290911690630a9837c5906044016020604051808303816000875af1158015611255573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127991906131da565b60048701549091506112969083906001600160a01b031685611bcb565b6004860154865460058801546040516001600160a01b03938416938b16927ff50338be3ffa7cdbebca76c758cfd1745fb4abe5bd3736c2dbf0cc6483a7b93f926112e892879060028e01908c90613321565b60405180910390a3505050505050610c5d600160c955565b6113216040518060600160405280602181526020016136f6602191396127dc565b61012f80549082905560408051828152602081018490527f85814f0246fcd999c88af70c9e6238211e79444ff07ec745b80aed19ddb268c891015b60405180910390a15050565b6113996040518060400160405280601081526020016f726573756d6541756374696f6e73282960801b8152506127dc565b6101325460ff166113ec5760405162461bcd60e51b815260206004820152601760248201527f41756374696f6e7320617265206e6f742070617573656400000000000000000060448201526064016104f1565b610132805460ff191690556040513381527f91b812e075fb9190eebe2d938c00a7179d150156469a467ec60a290035f4635a906020015b60405180910390a1565b61146b6040518060400160405280601b81526020017f757064617465496e63656e746976654270732875696e743235362900000000008152506127dc565b806000036114bb5760405162461bcd60e51b815260206004820152601a60248201527f696e63656e74697665427073206d757374206e6f74206265203000000000000060448201526064016104f1565b61013080549082905560408051828152602081018490527f3d438fa36c5052935d12a6925d1660c8150c74ef11ca672d4279bc6fd41b8bcf910161135c565b61151b604051806060016040528060238152602001613717602391396127dc565b806000036115775760405162461bcd60e51b815260206004820152602360248201527f5f6e657874426964646572426c6f636b4c696d6974206d757374206e6f74206260448201526206520360ec1b60648201526084016104f1565b61013180549082905560408051828152602081018490527f3f22dba09ee9845bd2be6926fea5337a0db935ca059cbb205d62174783e29664910161135c565b6115be612694565b6115c8600061287a565b565b6001600160a01b038216600090815260fb602090815260408083203384529091528120549060001983146115fe5782611600565b815b90508181111561164257604051639d2df25760e01b81526001600160a01b038516600482015233602482015260448101839052606481018290526084016104f1565b6001600160a01b038416600081815260fb602090815260408083203384528252808320858703905592825260fc9052908120805483929061168490849061324a565b909155505060405181815233906001600160a01b038616907f8d0aa4a41b0206123877a3705f51d17acf5f31dc241d24188abb2b881297ecfd9060200160405180910390a36116dd6001600160a01b03851633836127ac565b50505050565b60655433906001600160a01b031681146117515760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016104f1565b610c5d8161287a565b61178a6040518060400160405280600f81526020016e706175736541756374696f6e73282960881b8152506127dc565b6101325460ff16156117de5760405162461bcd60e51b815260206004820152601b60248201527f41756374696f6e732061726520616c726561647920706175736564000000000060448201526064016104f1565b610132805460ff191660011790556040513381527fc1be5163c9ebecf05bfbd6c6ae7c2b6ce2d3c43088dffaf5270cbf951615049990602001611423565b611824612694565b61182d81612893565b61012d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fa87b964d321035d2165e484ff4b722dd6eae30606c0b98887d2ed1a34e594bfe90600090a35050565b600054610100900460ff16158080156118a05750600054600160ff909116105b806118ba5750303b1580156118ba575060005460ff166001145b61191d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104f1565b6000805460ff191660011790558015611940576000805461ff0019166101001790555b61194984612893565b826000036119995760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964206d696e696d756d20706f6f6c20626164206465627400000060448201526064016104f1565b6119a16128ba565b6119aa826128e9565b6119b2612910565b6119ba61293f565b61012f83905561012e80546001600160a01b0319166001600160a01b0386161790556064610133819055610131556103e861013055610132805460ff1916905580156116dd576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b611a6660405180606001604052806021815260200161373a602191396127dc565b61013380549082905560408051828152602081018490527f2a5be8a6b827e16c392d22522295794d6baff64565057a17b1f14c9d6c125a60910161135c565b611aad612694565b606580546001600160a01b0383166001600160a01b03199091168117909155611ade6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600260c95403611b685760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104f1565b600260c955565b6000600180830154610100900460ff166002811115611b9057611b90613021565b1492915050565b60048101546000906001600160a01b031615808015611bc45750610133548354611bc1919061327a565b43115b9392505050565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015611c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3691906131da565b905081811015611c785760405163861da4bd60e01b81526001600160a01b038516600482015230602482015260448101839052606481018290526084016104f1565b6116dd84848461296e565b6040516001600160a01b03808516602483015283166044820152606481018290526116dd9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a40565b600160c955565b61012d54604051637aee632d60e01b81526001600160a01b0383811660048301526000921690637aee632d90602401600060405180830381865afa158015611d41573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d6991908101906133ea565b9050816001600160a01b031681604001516001600160a01b031614611de05760405162461bcd60e51b815260206004820152602760248201527f636f6d7074726f6c6c657220646f65736e277420657869737420706f6f6c20726044820152666567697374727960c81b60648201526084016104f1565b6001600160a01b038216600090815261013460205260408120906001820154610100900460ff166002811115611e1857611e18613021565b1480611e41575060026001820154610100900460ff166002811115611e3f57611e3f613021565b145b611e835760405162461bcd60e51b815260206004820152601360248201527261756374696f6e206973206f6e2d676f696e6760681b60448201526064016104f1565b600060058201819055600682018190556002820154905b81811015611eee576000836002018281548110611eb957611eb9613197565b60009182526020808320909101546001600160a01b03168252600886019052604081205550611ee781613261565b9050611e9a565b50611efd600283016000612f22565b6000611f0885612b15565b9050805191506000611f1986612b83565b90506000808467ffffffffffffffff811115611f3757611f37613292565b604051908082528060200260200182016040528015611f60578160200160208202803683370190505b5090508467ffffffffffffffff811115611f7c57611f7c613292565b604051908082528060200260200182016040528015611fa5578160200160208202803683370190505b508051611fbc916002890191602090910190612f40565b5060005b85811015612264576000858281518110611fdc57611fdc613197565b60200260200101516001600160a01b031663bbcac5576040518163ffffffff1660e01b8152600401602060405180830381865afa158015612021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204591906131da565b9050846001600160a01b03166396e85ced87848151811061206857612068613197565b60200260200101516040518263ffffffff1660e01b815260040161209b91906001600160a01b0391909116815260200190565b600060405180830381600087803b1580156120b557600080fd5b505af11580156120c9573d6000803e3d6000fd5b505050506000670de0b6b3a764000082876001600160a01b031663fc57d4df8a87815181106120fa576120fa613197565b60200260200101516040518263ffffffff1660e01b815260040161212d91906001600160a01b0391909116815260200190565b602060405180830381865afa15801561214a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216e91906131da565b6121789190613209565b6121829190613228565b905061218e818661327a565b94508683815181106121a2576121a2613197565b60200260200101518960020184815481106121bf576121bf613197565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508189600801600089868151811061220657612206613197565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508184848151811061224557612245613197565b60200260200101818152505050508061225d90613261565b9050611fc0565b5061012f548210156122b85760405162461bcd60e51b815260206004820152601860248201527f706f6f6c20626164206465627420697320746f6f206c6f77000000000000000060448201526064016104f1565b826001600160a01b031663b62cad6961012e60009054906101000a90046001600160a01b03166001600160a01b031663c8ecc0d36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561231b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233f91906131bd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b15801561238057600080fd5b505af1158015612394573d6000803e3d6000fd5b505061012e5460405163534de8cf60e11b81526001600160a01b038c8116600483015260009450670de0b6b3a764000093509091169063a69bd19e90602401602060405180830381865afa1580156123f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241491906131da565b856001600160a01b03166341976e0961012e60009054906101000a90046001600160a01b03166001600160a01b031663c8ecc0d36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061249b91906131bd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156124df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250391906131da565b61250d9190613209565b6125179190613228565b90506000819050600061271061013054866125329190613209565b61253c9190613228565b612546908661327a565b90508281106125a4576101305461255f9061271061327a565b6125699086613209565b8261257661271080613209565b6125809190613209565b61258a9190613228565b60078a015560018901805460ff19169055600091506125cb565b806125af818461324a565b60018b8101805460ff1916909117905561271060078c01559250505b6125d5828461324a565b60038a01554389556001808a01805461ff00191661010083021790555060008960040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a6001600160a01b03167f56c1f0c5ea96c78d614c0246b1915086a325f09ce15526bd5d69b50232d681328a600001548b60010160009054906101000a900460ff168c600201888e600301548f6007015460405161267f969594939291906134e0565b60405180910390a25050505050505050505050565b6033546001600160a01b031633146115c85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f1565b6001600160a01b0381166127525760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b60648201526084016104f1565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0910161135c565b6040516001600160a01b038316602482015260448101829052610af690849063a9059cbb60e01b90606401611cb7565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab9061280f903390869060040161355a565b602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612850919061357e565b90508061287657333083604051634a3fa29360e01b81526004016104f1939291906135a0565b5050565b606580546001600160a01b0319169055610c5d81612be7565b6001600160a01b038116610c5d576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff166128e15760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c39565b600054610100900460ff16610c685760405162461bcd60e51b81526004016104f1906135d5565b600054610100900460ff166129375760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c69565b600054610100900460ff166129665760405162461bcd60e51b81526004016104f1906135d5565b6115c8612c90565b600061297b848484612cb7565b9050806116dd576001600160a01b03808516600090815260fb60209081526040808320938716835292905290812080548492906129b990849061327a565b90915550506001600160a01b038416600090815260fc6020526040812080548492906129e690849061327a565b92505081905550826001600160a01b0316846001600160a01b03167fca6abeb3233ce8fb0de841c83102849b2d4165b80c92c5627899a5148ab4650084604051612a3291815260200190565b60405180910390a350505050565b6000612a95826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612da29092919063ffffffff16565b9050805160001480612ab6575080806020019051810190612ab6919061357e565b610af65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016104f1565b6060816001600160a01b031663b0772d0b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015612b55573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b7d9190810190613620565b92915050565b6000816001600160a01b0316637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7d91906131bd565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16612c605760405162461bcd60e51b81526004016104f1906135d5565b6115c83361287a565b600054610100900460ff16611cee5760405162461bcd60e51b81526004016104f1906135d5565b600054610100900460ff166115c85760405162461bcd60e51b81526004016104f1906135d5565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283918291881690612d159085906136c6565b6000604051808303816000865af19150503d8060008114612d52576040519150601f19603f3d011682016040523d82523d6000602084013e612d57565b606091505b5091509150818015612d81575080511580612d81575080806020019051810190612d81919061357e565b8015612d9757506000876001600160a01b03163b115b979650505050505050565b6060612db18484600085612db9565b949350505050565b606082471015612e1a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016104f1565b600080866001600160a01b03168587604051612e3691906136c6565b60006040518083038185875af1925050503d8060008114612e73576040519150601f19603f3d011682016040523d82523d6000602084013e612e78565b606091505b5091509150612d978783838760608315612ef3578251600003612eec576001600160a01b0385163b612eec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104f1565b5081612db1565b612db18383815115612f085781518083602001fd5b8060405162461bcd60e51b81526004016104f191906136e2565b5080546000825590600052602060002090810190610c5d9190612fa5565b828054828255906000526020600020908101928215612f95579160200282015b82811115612f9557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612f60565b50612fa1929150612fa5565b5090565b5b80821115612fa15760008155600101612fa6565b6001600160a01b0381168114610c5d57600080fd5b600080600060608486031215612fe457600080fd5b8335612fef81612fba565b95602085013595506040909401359392505050565b60006020828403121561301657600080fd5b8135611bc481612fba565b634e487b7160e01b600052602160045260246000fd5b6002811061304757613047613021565b9052565b8881526101008101613060602083018a613037565b6003881061307057613070613021565b604082019790975260608101959095526001600160a01b0393909316608085015260a084019190915260c083015260e09091015292915050565b6000602082840312156130bc57600080fd5b5035919050565b600080604083850312156130d657600080fd5b82356130e181612fba565b946020939093013593505050565b6000806040838503121561310257600080fd5b823561310d81612fba565b9150602083013561311d81612fba565b809150509250929050565b60008060006060848603121561313d57600080fd5b833561314881612fba565b925060208401359150604084013561315f81612fba565b809150509250925092565b60208082526013908201527237379037b716b3b7b4b7339030bab1ba34b7b760691b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b80516131b881612fba565b919050565b6000602082840312156131cf57600080fd5b8151611bc481612fba565b6000602082840312156131ec57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613223576132236131f3565b500290565b60008261324557634e487b7160e01b600052601260045260246000fd5b500490565b60008282101561325c5761325c6131f3565b500390565b600060018201613273576132736131f3565b5060010190565b6000821982111561328d5761328d6131f3565b500190565b634e487b7160e01b600052604160045260246000fd5b6000815480845260208085019450836000528060002060005b838110156132e65781546001600160a01b0316875295820195600191820191016132c1565b509495945050505050565b600081518084526020808501945080840160005b838110156132e657815187529582019590820190600101613305565b85815284602082015283604082015260a06060820152600061334660a08301856132a8565b828103608084015261335881856132f1565b98975050505050505050565b60405160a0810167ffffffffffffffff8111828210171561338757613387613292565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156133b6576133b6613292565b604052919050565b60005b838110156133d95781810151838201526020016133c1565b838111156116dd5750506000910152565b600060208083850312156133fd57600080fd5b825167ffffffffffffffff8082111561341557600080fd5b9084019060a0828703121561342957600080fd5b613431613364565b82518281111561344057600080fd5b8301601f8101881361345157600080fd5b80518381111561346357613463613292565b613475601f8201601f1916870161338d565b9350808452888682840101111561348b57600080fd5b61349a818786018885016133be565b50508181526134aa8484016131ad565b848201526134ba604084016131ad565b604082015260608301516060820152608083015160808201528094505050505092915050565b8681526134f06020820187613037565b60c06040820152600061350660c08301876132a8565b828103606084015261351881876132f1565b6080840195909552505060a00152949350505050565b600081518084526135468160208601602086016133be565b601f01601f19169290920160200192915050565b6001600160a01b0383168152604060208201819052600090612db19083018461352e565b60006020828403121561359057600080fd5b81518015158114611bc457600080fd5b6001600160a01b038481168252831660208201526060604082018190526000906135cc9083018461352e565b95945050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6000602080838503121561363357600080fd5b825167ffffffffffffffff8082111561364b57600080fd5b818501915085601f83011261365f57600080fd5b81518181111561367157613671613292565b8060051b915061368284830161338d565b818152918301840191848101908884111561369c57600080fd5b938501935b8385101561335857845192506136b683612fba565b82825293850193908501906136a1565b600082516136d88184602087016133be565b9190910192915050565b602081526000611bc4602083018461352e56fe7570646174654d696e696d756d506f6f6c426164446562742875696e74323536297570646174654e657874426964646572426c6f636b4c696d69742875696e743235362975706461746557616974466f7246697273744269646465722875696e7432353629a2646970667358221220cdd1210a9ea7d2dc0776d5d22df850b673565d10413487e9a45d7df9c7039cdf64736f6c634300080d0033", + "devdoc": { + "author": "Venus", + "errors": { + "InsufficientBalance(address,address,uint256,uint256)": [ + { + "params": { + "amount": "The amount of tokens the contract is trying to transfer", + "availableBalance": "The amount of tokens the contract currently has", + "recipient": "The recipient of the transfer", + "token": "The token the contract is trying to transfer" + } + } + ], + "InsufficientDebt(address,address,uint256,uint256)": [ + { + "params": { + "amount": "The amount of tokens the user is trying to claim", + "owedAmount": "The amount of tokens the contract owes to the user", + "token": "The token the user is trying to claim" + } + } + ] + }, + "kind": "dev", + "methods": { + "acceptOwnership()": { + "details": "The new owner accepts the ownership transfer." + }, + "claimTokenDebt(address,uint256)": { + "custom:error": "InsufficientDebt The contract doesn't have enough debt to the user", + "params": { + "amount_": "The amount of tokens to claim (or max uint256 to claim all)", + "token": "The token to claim" + } + }, + "closeAuction(address)": { + "custom:event": "Emits AuctionClosed event on successful close", + "params": { + "comptroller": "Comptroller address of the pool" + } + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "initialize(address,uint256,address)": { + "custom:error": "ZeroAddressNotAllowed is thrown when convertible base asset address is zeroZeroAddressNotAllowed is thrown when risk fund address is zero", + "params": { + "accessControlManager_": "AccessControlManager contract address", + "minimumPoolBadDebt_": "Minimum bad debt in base asset for a pool to start auction", + "riskFund_": "RiskFund contract address" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pauseAuctions()": { + "custom:access": "Restricted by ACM", + "custom:error": "Errors is auctions are paused", + "custom:event": "Emits AuctionsPaused on success" + }, + "pendingOwner()": { + "details": "Returns the address of the pending owner." + }, + "placeBid(address,uint256,uint256)": { + "custom:event": "Emits BidPlaced event on success", + "params": { + "auctionStartBlock": "The block number when auction started", + "bidBps": "The bid percent of the risk fund or bad debt depending on auction type", + "comptroller": "Comptroller address of the pool" + } + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "restartAuction(address)": { + "custom:event": "Emits AuctionRestarted event on successful restart", + "params": { + "comptroller": "Address of the pool" + } + }, + "resumeAuctions()": { + "custom:access": "Restricted by ACM", + "custom:error": "Errors is auctions are active", + "custom:event": "Emits AuctionsResumed on success" + }, + "setAccessControlManager(address)": { + "custom:access": "Only Governance", + "custom:event": "Emits NewAccessControlManager event", + "details": "Admin function to set address of AccessControlManager", + "params": { + "accessControlManager_": "The new address of the AccessControlManager" + } + }, + "startAuction(address)": { + "custom:event": "Emits AuctionStarted event on successErrors if auctions are paused", + "params": { + "comptroller": "Comptroller address of the pool" + } + }, + "transferOwnership(address)": { + "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." + }, + "updateIncentiveBps(uint256)": { + "custom:access": "Restricted by ACM", + "custom:event": "Emits IncentiveBpsUpdated on success", + "params": { + "_incentiveBps": "New incentive BPS" + } + }, + "updateMinimumPoolBadDebt(uint256)": { + "custom:access": "Restricted by ACM", + "custom:event": "Emits MinimumPoolBadDebtUpdated on success", + "params": { + "_minimumPoolBadDebt": "Minimum bad debt in BUSD for a pool to start auction" + } + }, + "updateNextBidderBlockLimit(uint256)": { + "custom:access": "Restricted by ACM", + "custom:event": "Emits NextBidderBlockLimitUpdated on success", + "params": { + "_nextBidderBlockLimit": "New next bidder block limit" + } + }, + "updatePoolRegistry(address)": { + "custom:access": "Restricted to owner", + "custom:error": "ZeroAddressNotAllowed is thrown when pool registry address is zero", + "custom:event": "Emits PoolRegistryUpdated on success", + "details": "After Pool Registry is deployed we need to set the pool registry address", + "params": { + "poolRegistry_": "Address of pool registry contract" + } + }, + "updateWaitForFirstBidder(uint256)": { + "custom:access": "Restricted by ACM", + "custom:event": "Emits WaitForFirstBidderUpdated on success", + "params": { + "_waitForFirstBidder": "New wait for first bidder block count" + } + } + }, + "stateVariables": { + "MAX_BPS": { + "details": "Max basis points i.e., 100%" + } + }, + "title": "Shortfall", + "version": 1 + }, + "userdoc": { + "errors": { + "InsufficientBalance(address,address,uint256,uint256)": [ + { + "notice": "Thrown if trying to transfer more tokens than the contract currently has" + } + ], + "InsufficientDebt(address,address,uint256,uint256)": [ + { + "notice": "Thrown if the user tries to claim more tokens than they are owed" + } + ], + "Unauthorized(address,address,string)": [ + { + "notice": "Thrown when the action is prohibited by AccessControlManager" + } + ], + "ZeroAddressNotAllowed()": [ + { + "notice": "Thrown if the supplied address is a zero address where it is not allowed" + } + ] + }, + "events": { + "AuctionClosed(address,uint256,address,uint256,uint256,address[],uint256[])": { + "notice": "Emitted when a auction is completed" + }, + "AuctionRestarted(address,uint256)": { + "notice": "Emitted when a auction is restarted" + }, + "AuctionStarted(address,uint256,uint8,address[],uint256[],uint256,uint256)": { + "notice": "Emitted when a auction starts" + }, + "AuctionsPaused(address)": { + "notice": "Emitted when auctions are paused" + }, + "AuctionsResumed(address)": { + "notice": "Emitted when auctions are unpaused" + }, + "BidPlaced(address,uint256,uint256,address)": { + "notice": "Emitted when a bid is placed" + }, + "IncentiveBpsUpdated(uint256,uint256)": { + "notice": "Emitted when incentiveBps is updated" + }, + "MinimumPoolBadDebtUpdated(uint256,uint256)": { + "notice": "Emitted when minimum pool bad debt is updated" + }, + "NewAccessControlManager(address,address)": { + "notice": "Emitted when access control manager contract address is changed" + }, + "NextBidderBlockLimitUpdated(uint256,uint256)": { + "notice": "Emitted when next bidder block limit is updated" + }, + "PoolRegistryUpdated(address,address)": { + "notice": "Emitted when pool registry address is updated" + }, + "TokenDebtAdded(address,address,uint256)": { + "notice": "Emitted when the contract's debt to the user is increased due to a failed transfer" + }, + "TokenDebtClaimed(address,address,uint256)": { + "notice": "Emitted when a user claims tokens that the contract owes them" + }, + "WaitForFirstBidderUpdated(uint256,uint256)": { + "notice": "Emitted when wait for first bidder block count is updated" + } + }, + "kind": "user", + "methods": { + "accessControlManager()": { + "notice": "Returns the address of the access control manager contract" + }, + "auctions(address)": { + "notice": "Auctions for each pool" + }, + "auctionsPaused()": { + "notice": "Boolean of if auctions are paused" + }, + "claimTokenDebt(address,uint256)": { + "notice": "Transfers the tokens we owe to msg.sender, if any" + }, + "closeAuction(address)": { + "notice": "Close an auction" + }, + "incentiveBps()": { + "notice": "Incentive to auction participants, initial value set to 1000 or 10%" + }, + "initialize(address,uint256,address)": { + "notice": "Initialize the shortfall contract" + }, + "minimumPoolBadDebt()": { + "notice": "Minimum USD debt in pool for shortfall to trigger" + }, + "nextBidderBlockLimit()": { + "notice": "Time to wait for next bidder. Initially waits for 100 blocks" + }, + "pauseAuctions()": { + "notice": "Pause auctions. This disables starting new auctions but lets the current auction finishes" + }, + "placeBid(address,uint256,uint256)": { + "notice": "Place a bid greater than the previous in an ongoing auction" + }, + "poolRegistry()": { + "notice": "Pool registry address" + }, + "restartAuction(address)": { + "notice": "Restart an auction" + }, + "resumeAuctions()": { + "notice": "Resume paused auctions." + }, + "riskFund()": { + "notice": "Risk fund address" + }, + "setAccessControlManager(address)": { + "notice": "Sets the address of AccessControlManager" + }, + "startAuction(address)": { + "notice": "Start a auction when there is not currently one active" + }, + "tokenDebt(address,address)": { + "notice": "Mapping (IERC20Upgradeable token => (address user => uint256 amount)). Tracks failed transfers: when a token transfer fails, we record the amount of the transfer, so that the user can redeem this debt later." + }, + "totalTokenDebt(address)": { + "notice": "Mapping (IERC20Upgradeable token => uint256 amount) shows how many tokens the contract owes to all users. This is useful for accounting to understand how much of balanceOf(address(this)) is already owed to users." + }, + "updateIncentiveBps(uint256)": { + "notice": "Updates the incentive BPS" + }, + "updateMinimumPoolBadDebt(uint256)": { + "notice": "Update minimum pool bad debt to start auction" + }, + "updateNextBidderBlockLimit(uint256)": { + "notice": "Update next bidder block limit which is used determine when an auction can be closed" + }, + "updatePoolRegistry(address)": { + "notice": "Update the pool registry this shortfall supports" + }, + "updateWaitForFirstBidder(uint256)": { + "notice": "Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted" + }, + "waitForFirstBidder()": { + "notice": "Time to wait for first bidder. Initially waits for 100 blocks" + } + }, + "notice": "Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset` is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value. This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise, if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the risk fund in exchange for paying off all the pool's bad debt.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 290, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 293, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1397, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 162, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 282, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 71, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_pendingOwner", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 150, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 3341, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_accessControlManager", + "offset": 0, + "slot": "151", + "type": "t_contract(IAccessControlManagerV8)3525" + }, + { + "astId": 3346, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 466, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "_status", + "offset": 0, + "slot": "201", + "type": "t_uint256" + }, + { + "astId": 535, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 19411, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "tokenDebt", + "offset": 0, + "slot": "251", + "type": "t_mapping(t_contract(IERC20Upgradeable)614,t_mapping(t_address,t_uint256))" + }, + { + "astId": 19417, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "totalTokenDebt", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_contract(IERC20Upgradeable)614,t_uint256)" + }, + { + "astId": 19422, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "__gap", + "offset": 0, + "slot": "253", + "type": "t_array(t_uint256)48_storage" + }, + { + "astId": 14516, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "poolRegistry", + "offset": 0, + "slot": "301", + "type": "t_address" + }, + { + "astId": 14520, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "riskFund", + "offset": 0, + "slot": "302", + "type": "t_contract(IRiskFund)13073" + }, + { + "astId": 14523, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "minimumPoolBadDebt", + "offset": 0, + "slot": "303", + "type": "t_uint256" + }, + { + "astId": 14526, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "incentiveBps", + "offset": 0, + "slot": "304", + "type": "t_uint256" + }, + { + "astId": 14529, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "nextBidderBlockLimit", + "offset": 0, + "slot": "305", + "type": "t_uint256" + }, + { + "astId": 14532, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "auctionsPaused", + "offset": 0, + "slot": "306", + "type": "t_bool" + }, + { + "astId": 14535, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "waitForFirstBidder", + "offset": 0, + "slot": "307", + "type": "t_uint256" + }, + { + "astId": 14541, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "auctions", + "offset": 0, + "slot": "308", + "type": "t_mapping(t_address,t_struct(Auction)14500_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_contract(VToken)18767)dyn_storage": { + "base": "t_contract(VToken)18767", + "encoding": "dynamic_array", + "label": "contract VToken[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)48_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[48]", + "numberOfBytes": "1536" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IAccessControlManagerV8)3525": { + "encoding": "inplace", + "label": "contract IAccessControlManagerV8", + "numberOfBytes": "20" + }, + "t_contract(IERC20Upgradeable)614": { + "encoding": "inplace", + "label": "contract IERC20Upgradeable", + "numberOfBytes": "20" + }, + "t_contract(IRiskFund)13073": { + "encoding": "inplace", + "label": "contract IRiskFund", + "numberOfBytes": "20" + }, + "t_contract(VToken)18767": { + "encoding": "inplace", + "label": "contract VToken", + "numberOfBytes": "20" + }, + "t_enum(AuctionStatus)14467": { + "encoding": "inplace", + "label": "enum Shortfall.AuctionStatus", + "numberOfBytes": "1" + }, + "t_enum(AuctionType)14463": { + "encoding": "inplace", + "label": "enum Shortfall.AuctionType", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_struct(Auction)14500_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct Shortfall.Auction)", + "numberOfBytes": "32", + "value": "t_struct(Auction)14500_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_contract(IERC20Upgradeable)614,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_contract(IERC20Upgradeable)614", + "label": "mapping(contract IERC20Upgradeable => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_contract(IERC20Upgradeable)614,t_uint256)": { + "encoding": "mapping", + "key": "t_contract(IERC20Upgradeable)614", + "label": "mapping(contract IERC20Upgradeable => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_contract(VToken)18767,t_uint256)": { + "encoding": "mapping", + "key": "t_contract(VToken)18767", + "label": "mapping(contract VToken => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(Auction)14500_storage": { + "encoding": "inplace", + "label": "struct Shortfall.Auction", + "members": [ + { + "astId": 14469, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "startBlock", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 14472, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "auctionType", + "offset": 0, + "slot": "1", + "type": "t_enum(AuctionType)14463" + }, + { + "astId": 14475, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "status", + "offset": 1, + "slot": "1", + "type": "t_enum(AuctionStatus)14467" + }, + { + "astId": 14479, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "markets", + "offset": 0, + "slot": "2", + "type": "t_array(t_contract(VToken)18767)dyn_storage" + }, + { + "astId": 14481, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "seizedRiskFund", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 14483, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "highestBidder", + "offset": 0, + "slot": "4", + "type": "t_address" + }, + { + "astId": 14485, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "highestBidBps", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 14487, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "highestBidBlock", + "offset": 0, + "slot": "6", + "type": "t_uint256" + }, + { + "astId": 14489, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "startBidBps", + "offset": 0, + "slot": "7", + "type": "t_uint256" + }, + { + "astId": 14494, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "marketDebt", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_contract(VToken)18767,t_uint256)" + }, + { + "astId": 14499, + "contract": "contracts/Shortfall/Shortfall.sol:Shortfall", + "label": "bidAmount", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_contract(VToken)18767,t_uint256)" + } + ], + "numberOfBytes": "320" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} diff --git a/deployments/bsctestnet/Shortfall_Proxy.json b/deployments/bsctestnet/Shortfall_Proxy.json new file mode 100644 index 000000000..aa8e5494d --- /dev/null +++ b/deployments/bsctestnet/Shortfall_Proxy.json @@ -0,0 +1,267 @@ +{ + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "receipt": { + "to": null, + "from": "0x2Ce1d0ffD7E869D9DF33e28552b12DdDed326706", + "contractAddress": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "transactionIndex": 2, + "gasUsed": "933014", + "logsBloom": "0x1000000000000000000000000000000040000000000000000080000800000000000000400000000000000000000000000000000000000000400000000000c000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000000000800000000800000000000000000000000400000000040000000000000000000000000000000000080000000000000800000000000000000000000000000000400200000000000800000000000000000000000000020000000000000000000040000000000000400000000000000000020000020000000000000000000000000000000004800000000000000000000000000", + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af", + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000040ec22d1aa01236de2fb3df049de9f104a25c87c" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + }, + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002ce1d0ffd7e869d9df33e28552b12ddded326706" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + }, + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": ["0x66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa0"], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa", + "logIndex": 2, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + }, + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 3, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + }, + { + "transactionIndex": 2, + "blockNumber": 33267929, + "transactionHash": "0x32436db1f809d562f87bf32c706b490227a2e136f05a4e95f3347ef47bbd1631", + "address": "0x503574a82fE2A9f968d355C8AAc1Ba0481859369", + "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007877ffd62649b6a1557b55d4c20fcbab17344c91", + "logIndex": 4, + "blockHash": "0x87fa925b70d9fd9bc01919037eb14bb5d3784950e1bcc48433816b9b8c73d5af" + } + ], + "blockNumber": 33267929, + "cumulativeGasUsed": "1009663", + "status": 1, + "byzantium": true + }, + "args": [ + "0x40Ec22d1aA01236dE2FB3dF049DE9f104A25c87C", + "0x7877fFd62649b6A1557B55D4c20fcBaB17344C91", + "0xc350a1b5000000000000000000000000487cef72dacabd7e12e633bb3b63815a386f701200000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000045f8a08f534f34a97187626e05d4b6648eeaa9aa" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\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 function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsctestnet/solcInputs/394b060e0e484d4aa39aea929deecf07.json b/deployments/bsctestnet/solcInputs/394b060e0e484d4aa39aea929deecf07.json new file mode 100644 index 000000000..9e6416284 --- /dev/null +++ b/deployments/bsctestnet/solcInputs/394b060e0e484d4aa39aea929deecf07.json @@ -0,0 +1,210 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides 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} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\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" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\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" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20Upgradeable 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\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. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\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[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\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 {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\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 * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\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 * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\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 revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\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 * _Available since v3.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\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 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 */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title Venus Access Control Contract.\n * @dev The AccessControlledV8 contract is a wrapper around the OpenZeppelin AccessControl contract\n * It provides a standardized way to control access to methods within the Venus Smart Contract Ecosystem.\n * The contract allows the owner to set an AccessControlManager contract address.\n * It can restrict method calls based on the sender's role and the method's signature.\n */\n\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\n /// @notice Access control manager contract\n IAccessControlManagerV8 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 /// @notice Thrown when the action is prohibited by AccessControlManager\n error Unauthorized(address sender, address calledContract, string methodSignature);\n\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n }\n\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Sets the address of AccessControlManager\n * @dev Admin function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n * @custom:event Emits NewAccessControlManager event\n * @custom:access Only Governance\n */\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Returns the address of the access control manager contract\n */\n function accessControlManager() external view returns (IAccessControlManagerV8) {\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 = IAccessControlManagerV8(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(msg.sender, address(this), signature);\n }\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title Venus Access Control Contract\n * @author venus\n * @dev This contract is a wrapper of OpenZeppelin AccessControl\n *\t\textending it in a way to standartize access control\n *\t\twithin Venus Smart Contract Ecosystem\n */\ncontract AccessControlManager is AccessControl, IAccessControlManagerV8 {\n /// @notice Emitted when an account is given a permission to a certain contract function\n /// @dev If contract address is 0x000..0 this means that the account is a default admin of this function and\n /// can call any contract function with this signature\n event PermissionGranted(address account, address contractAddress, string functionSig);\n\n /// @notice Emitted when an account is revoked a permission to a certain contract function\n event PermissionRevoked(address account, address contractAddress, string functionSig);\n\n constructor() {\n // Grant the contract deployer the default admin role: it will be able\n // to grant and revoke any roles\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\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 * @param contractAddress address of contract for which call permissions will be granted\n * @dev if contractAddress is zero address, the account can access the specified function\n * on **any** contract managed by this ACL\n * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n * @param accountToPermit account that will be given access to the contract function\n * @custom:event Emits a {RoleGranted} and {PermissionGranted} events.\n */\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n grantRole(role, accountToPermit);\n emit PermissionGranted(accountToPermit, contractAddress, functionSig);\n }\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(uint256,bool)\"\n * @custom:event Emits {RoleRevoked} and {PermissionRevoked} events.\n */\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n revokeRole(role, accountToRevoke);\n emit PermissionRevoked(accountToRevoke, contractAddress, functionSig);\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev Since restricted contracts using this function as a permission hook, we can get contracts address with msg.sender\n * @param account for which call permissions will be checked\n * @param functionSig restricted function signature e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n *\n */\n function isAllowedToCall(address account, string calldata functionSig) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(msg.sender, functionSig));\n\n if (hasRole(role, account)) {\n return true;\n } else {\n role = keccak256(abi.encodePacked(address(0), functionSig));\n return hasRole(role, account);\n }\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev This function is used as a view function to check permissions rather than contract hook for access restriction check.\n * @param account for which call permissions will be checked against\n * @param contractAddress address of the restricted contract\n * @param functionSig signature of the restricted function e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n */\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n return hasRole(role, account);\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\ninterface IAccessControlManagerV8 is IAccessControl {\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\n\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) external;\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/oracle/contracts/interfaces/FeedRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface FeedRegistryInterface {\n function latestRoundDataByName(\n string memory base,\n string memory quote\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function decimalsByName(string memory base, string memory quote) external view returns (uint8);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface OracleInterface {\n function getPrice(address asset) external view returns (uint256);\n}\n\ninterface ResilientOracleInterface is OracleInterface {\n function updatePrice(address vToken) external;\n\n function updateAssetPrice(address asset) external;\n\n function getUnderlyingPrice(address vToken) external view returns (uint256);\n}\n\ninterface TwapInterface is OracleInterface {\n function updateTwap(address asset) external returns (uint256);\n}\n\ninterface BoundValidatorInterface {\n function validatePriceWithAnchorPrice(\n address asset,\n uint256 reporterPrice,\n uint256 anchorPrice\n ) external view returns (bool);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/PublicResolverInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity 0.8.13;\n\ninterface PublicResolverInterface {\n function addr(bytes32 node) external view returns (address payable);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/SIDRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity 0.8.13;\n\ninterface SIDRegistryInterface {\n function resolver(bytes32 node) external view returns (address);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/VBep20Interface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface VBep20Interface is IERC20Metadata {\n /**\n * @notice Underlying asset for this VToken\n */\n function underlying() external view returns (address);\n}\n" + }, + "@venusprotocol/oracle/contracts/oracles/BinanceOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/SIDRegistryInterface.sol\";\nimport \"../interfaces/FeedRegistryInterface.sol\";\nimport \"../interfaces/PublicResolverInterface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport \"../interfaces/OracleInterface.sol\";\n\n/**\n * @title BinanceOracle\n * @author Venus\n * @notice This oracle fetches price of assets from Binance.\n */\ncontract BinanceOracle is AccessControlledV8, OracleInterface {\n address public sidRegistryAddress;\n\n /// @notice Set this as asset address for BNB. This is the underlying address for vBNB\n address public constant BNB_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n /// @notice Max stale period configuration for assets\n mapping(string => uint256) public maxStalePeriod;\n\n /// @notice Override symbols to be compatible with Binance feed registry\n mapping(string => string) public symbols;\n\n event MaxStalePeriodAdded(string indexed asset, uint256 maxStalePeriod);\n\n event SymbolOverridden(string indexed symbol, string overriddenSymbol);\n\n /**\n * @notice Checks whether an address is null or not\n */\n modifier notNullAddress(address someone) {\n if (someone == address(0)) revert(\"can't be zero address\");\n _;\n }\n\n /// @notice Constructor for the implementation contract.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Used to set the max stale period of an asset\n * @param symbol The symbol of the asset\n * @param _maxStalePeriod The max stake period\n */\n function setMaxStalePeriod(string memory symbol, uint256 _maxStalePeriod) external {\n _checkAccessAllowed(\"setMaxStalePeriod(string,uint256)\");\n if (_maxStalePeriod == 0) revert(\"stale period can't be zero\");\n if (bytes(symbol).length == 0) revert(\"symbol cannot be empty\");\n\n maxStalePeriod[symbol] = _maxStalePeriod;\n emit MaxStalePeriodAdded(symbol, _maxStalePeriod);\n }\n\n /**\n * @notice Used to override a symbol when fetching price\n * @param symbol The symbol to override\n * @param overrideSymbol The symbol after override\n */\n function setSymbolOverride(string calldata symbol, string calldata overrideSymbol) external {\n _checkAccessAllowed(\"setSymbolOverride(string,string)\");\n if (bytes(symbol).length == 0) revert(\"symbol cannot be empty\");\n\n symbols[symbol] = overrideSymbol;\n emit SymbolOverridden(symbol, overrideSymbol);\n }\n\n /**\n * @notice Sets the contracts required to fetch prices\n * @param _sidRegistryAddress Address of SID registry\n * @param _accessControlManager Address of the access control manager contract\n */\n function initialize(\n address _sidRegistryAddress,\n address _accessControlManager\n ) external initializer notNullAddress(_sidRegistryAddress) {\n sidRegistryAddress = _sidRegistryAddress;\n __AccessControlled_init(_accessControlManager);\n }\n\n /**\n * @notice Uses Space ID to fetch the feed registry address\n * @return feedRegistryAddress Address of binance oracle feed registry.\n */\n function getFeedRegistryAddress() public view returns (address) {\n bytes32 nodeHash = 0x94fe3821e0768eb35012484db4df61890f9a6ca5bfa984ef8ff717e73139faff;\n\n SIDRegistryInterface sidRegistry = SIDRegistryInterface(sidRegistryAddress);\n address publicResolverAddress = sidRegistry.resolver(nodeHash);\n PublicResolverInterface publicResolver = PublicResolverInterface(publicResolverAddress);\n\n return publicResolver.addr(nodeHash);\n }\n\n /**\n * @notice Gets the price of a asset from the binance oracle\n * @param asset Address of the asset\n * @return Price in USD\n */\n function getPrice(address asset) public view returns (uint256) {\n string memory symbol;\n uint256 decimals;\n\n if (asset == BNB_ADDR) {\n symbol = \"BNB\";\n decimals = 18;\n } else {\n IERC20Metadata token = IERC20Metadata(asset);\n symbol = token.symbol();\n decimals = token.decimals();\n }\n\n string memory overrideSymbol = symbols[symbol];\n\n if (bytes(overrideSymbol).length != 0) {\n symbol = overrideSymbol;\n }\n\n return _getPrice(symbol, decimals);\n }\n\n function _getPrice(string memory symbol, uint256 decimals) internal view returns (uint256) {\n FeedRegistryInterface feedRegistry = FeedRegistryInterface(getFeedRegistryAddress());\n\n (, int256 answer, , uint256 updatedAt, ) = feedRegistry.latestRoundDataByName(symbol, \"USD\");\n if (answer <= 0) revert(\"invalid binance oracle price\");\n if (block.timestamp < updatedAt) revert(\"updatedAt exceeds block time\");\n\n uint256 deltaTime;\n unchecked {\n deltaTime = block.timestamp - updatedAt;\n }\n if (deltaTime > maxStalePeriod[symbol]) revert(\"binance oracle price expired\");\n\n uint256 decimalDelta = feedRegistry.decimalsByName(symbol, \"USD\");\n return (uint256(answer) * (10 ** (18 - decimalDelta))) * (10 ** (18 - decimals));\n }\n}\n" + }, + "@venusprotocol/oracle/contracts/oracles/ChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\n/**\n * @title ChainlinkOracle\n * @author Venus\n * @notice This oracle fetches prices of assets from the Chainlink oracle.\n */\ncontract ChainlinkOracle is AccessControlledV8, OracleInterface {\n struct TokenConfig {\n /// @notice Underlying token address, which can't be a null address\n /// @notice Used to check if a token is supported\n /// @notice 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB for BNB\n address asset;\n /// @notice Chainlink feed address\n address feed;\n /// @notice Price expiration period of this asset\n uint256 maxStalePeriod;\n }\n\n /// @notice Set this as asset address for BNB. This is the underlying address for vBNB\n address public constant BNB_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n /// @notice Manually set an override price, useful under extenuating conditions such as price feed failure\n mapping(address => uint256) public prices;\n\n /// @notice Token config by assets\n mapping(address => TokenConfig) public tokenConfigs;\n\n /// @notice Emit when a price is manually set\n event PricePosted(address indexed asset, uint256 previousPriceMantissa, uint256 newPriceMantissa);\n\n /// @notice Emit when a token config is added\n event TokenConfigAdded(address indexed asset, address feed, uint256 maxStalePeriod);\n\n modifier notNullAddress(address someone) {\n if (someone == address(0)) revert(\"can't be zero address\");\n _;\n }\n\n /// @notice Constructor for the implementation contract.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Manually set the price of a given asset\n * @param asset Asset address\n * @param price Asset price in 18 decimals\n * @custom:access Only Governance\n * @custom:event Emits PricePosted event on succesfully setup of asset price\n */\n function setDirectPrice(address asset, uint256 price) external notNullAddress(asset) {\n _checkAccessAllowed(\"setDirectPrice(address,uint256)\");\n\n uint256 previousPriceMantissa = prices[asset];\n prices[asset] = price;\n emit PricePosted(asset, previousPriceMantissa, price);\n }\n\n /**\n * @notice Add multiple token configs at the same time\n * @param tokenConfigs_ config array\n * @custom:access Only Governance\n * @custom:error Zero length error thrown, if length of the array in parameter is 0\n */\n function setTokenConfigs(TokenConfig[] memory tokenConfigs_) external {\n if (tokenConfigs_.length == 0) revert(\"length can't be 0\");\n uint256 numTokenConfigs = tokenConfigs_.length;\n for (uint256 i; i < numTokenConfigs; ) {\n setTokenConfig(tokenConfigs_[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Initializes the owner of the contract\n * @param accessControlManager_ Address of the access control manager contract\n */\n function initialize(address accessControlManager_) external initializer {\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Add single token config. asset & feed cannot be null addresses and maxStalePeriod must be positive\n * @param tokenConfig Token config struct\n * @custom:access Only Governance\n * @custom:error NotNullAddress error is thrown if asset address is null\n * @custom:error NotNullAddress error is thrown if token feed address is null\n * @custom:error Range error is thrown if maxStale period of token is not greater than zero\n * @custom:event Emits TokenConfigAdded event on succesfully setting of the token config\n */\n function setTokenConfig(\n TokenConfig memory tokenConfig\n ) public notNullAddress(tokenConfig.asset) notNullAddress(tokenConfig.feed) {\n _checkAccessAllowed(\"setTokenConfig(TokenConfig)\");\n\n if (tokenConfig.maxStalePeriod == 0) revert(\"stale period can't be zero\");\n tokenConfigs[tokenConfig.asset] = tokenConfig;\n emit TokenConfigAdded(tokenConfig.asset, tokenConfig.feed, tokenConfig.maxStalePeriod);\n }\n\n /**\n * @notice Gets the price of a asset from the chainlink oracle\n * @param asset Address of the asset\n * @return Price in USD from Chainlink or a manually set price for the asset\n */\n function getPrice(address asset) public view returns (uint256) {\n uint256 decimals;\n\n if (asset == BNB_ADDR) {\n decimals = 18;\n } else {\n IERC20Metadata token = IERC20Metadata(asset);\n decimals = token.decimals();\n }\n\n return _getPriceInternal(asset, decimals);\n }\n\n /**\n * @notice Gets the Chainlink price for a given asset\n * @param asset address of the asset\n * @param decimals decimals of the asset\n * @return price Asset price in USD or a manually set price of the asset\n */\n function _getPriceInternal(address asset, uint256 decimals) internal view returns (uint256 price) {\n uint256 tokenPrice = prices[asset];\n if (tokenPrice != 0) {\n price = tokenPrice;\n } else {\n price = _getChainlinkPrice(asset);\n }\n\n uint256 decimalDelta = 18 - decimals;\n return price * (10 ** decimalDelta);\n }\n\n /**\n * @notice Get the Chainlink price for an asset, revert if token config doesn't exist\n * @dev The precision of the price feed is used to ensure the returned price has 18 decimals of precision\n * @param asset Address of the asset\n * @return price Price in USD, with 18 decimals of precision\n * @custom:error NotNullAddress error is thrown if the asset address is null\n * @custom:error Price error is thrown if the Chainlink price of asset is not greater than zero\n * @custom:error Timing error is thrown if current timestamp is less than the last updatedAt timestamp\n * @custom:error Timing error is thrown if time difference between current time and last updated time\n * is greater than maxStalePeriod\n */\n function _getChainlinkPrice(\n address asset\n ) private view notNullAddress(tokenConfigs[asset].asset) returns (uint256) {\n TokenConfig memory tokenConfig = tokenConfigs[asset];\n AggregatorV3Interface feed = AggregatorV3Interface(tokenConfig.feed);\n\n // note: maxStalePeriod cannot be 0\n uint256 maxStalePeriod = tokenConfig.maxStalePeriod;\n\n // Chainlink USD-denominated feeds store answers at 8 decimals, mostly\n uint256 decimalDelta = 18 - feed.decimals();\n\n (, int256 answer, , uint256 updatedAt, ) = feed.latestRoundData();\n if (answer <= 0) revert(\"chainlink price must be positive\");\n if (block.timestamp < updatedAt) revert(\"updatedAt exceeds block time\");\n\n uint256 deltaTime;\n unchecked {\n deltaTime = block.timestamp - updatedAt;\n }\n\n if (deltaTime > maxStalePeriod) revert(\"chainlink price expired\");\n\n return uint256(answer) * (10 ** decimalDelta);\n }\n}\n" + }, + "contracts/Comptroller.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { ComptrollerInterface } from \"./ComptrollerInterface.sol\";\nimport { ComptrollerStorage } from \"./ComptrollerStorage.sol\";\nimport { ExponentialNoError } from \"./ExponentialNoError.sol\";\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\nimport { MaxLoopsLimitHelper } from \"./MaxLoopsLimitHelper.sol\";\nimport { ensureNonzeroAddress } from \"./lib/validators.sol\";\n\n/**\n * @title Comptroller\n * @author Venus\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market’s corresponding liquidation threshold,\n * the borrow is eligible for liquidation.\n *\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\n * the `minLiquidatableCollateral` for the `Comptroller`:\n *\n * - `healAccount()`: This function is called to seize all of a given user’s collateral, requiring the `msg.sender` repay a certain percentage\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\n * verifying that the repay amount does not exceed the close factor.\n */\ncontract Comptroller is\n Ownable2StepUpgradeable,\n AccessControlledV8,\n ComptrollerStorage,\n ComptrollerInterface,\n ExponentialNoError,\n MaxLoopsLimitHelper\n{\n // PoolRegistry, immutable to save on gas\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n address public immutable poolRegistry;\n\n /// @notice Emitted when an account enters a market\n event MarketEntered(VToken indexed vToken, address indexed account);\n\n /// @notice Emitted when an account exits a market\n event MarketExited(VToken indexed vToken, address indexed account);\n\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(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\n\n /// @notice Emitted when liquidation threshold is changed by admin\n event NewLiquidationThreshold(\n VToken vToken,\n uint256 oldLiquidationThresholdMantissa,\n uint256 newLiquidationThresholdMantissa\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(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\n\n /// @notice Emitted when an action is paused on a market\n event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\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 the collateral threshold (in USD) for non-batch liquidations is changed\n event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\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 a rewards distributor is added\n event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\n\n /// @notice Emitted when a market is supported\n event MarketSupported(VToken vToken);\n\n /// @notice Thrown when collateral factor exceeds the upper bound\n error InvalidCollateralFactor();\n\n /// @notice Thrown when liquidation threshold exceeds the collateral factor\n error InvalidLiquidationThreshold();\n\n /// @notice Thrown when the action is only available to specific sender, but the real sender was different\n error UnexpectedSender(address expectedSender, address actualSender);\n\n /// @notice Thrown when the oracle returns an invalid price for some asset\n error PriceError(address vToken);\n\n /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\n error SnapshotError(address vToken, address user);\n\n /// @notice Thrown when the market is not listed\n error MarketNotListed(address market);\n\n /// @notice Thrown when a market has an unexpected comptroller\n error ComptrollerMismatch();\n\n /// @notice Thrown when user is not member of market\n error MarketNotCollateral(address vToken, address user);\n\n /**\n * @notice Thrown during the liquidation if user's total collateral amount is lower than\n * a predefined threshold. In this case only batch liquidations (either liquidateAccount\n * or healAccount) are available.\n */\n error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\n error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\n error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\n\n /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\n error InsufficientLiquidity();\n\n /// @notice Thrown when trying to liquidate a healthy account\n error InsufficientShortfall();\n\n /// @notice Thrown when trying to repay more than allowed by close factor\n error TooMuchRepay();\n\n /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\n error NonzeroBorrowBalance();\n\n /// @notice Thrown when trying to perform an action that is paused\n error ActionPaused(address market, Action action);\n\n /// @notice Thrown when trying to add a market that is already listed\n error MarketAlreadyListed(address market);\n\n /// @notice Thrown if the supply cap is exceeded\n error SupplyCapExceeded(address market, uint256 cap);\n\n /// @notice Thrown if the borrow cap is exceeded\n error BorrowCapExceeded(address market, uint256 cap);\n\n /// @param poolRegistry_ Pool registry address\n /// @custom:oz-upgrades-unsafe-allow constructor\n /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n constructor(address poolRegistry_) {\n ensureNonzeroAddress(poolRegistry_);\n\n poolRegistry = poolRegistry_;\n _disableInitializers();\n }\n\n /**\n * @param loopLimit Limit for the loops can iterate to avoid the DOS\n * @param accessControlManager Access control manager contract address\n */\n function initialize(uint256 loopLimit, address accessControlManager) external initializer {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager);\n\n _setMaxLoopsLimit(loopLimit);\n }\n\n /**\n * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\n * @param vTokens The list of addresses of the vToken markets to be enabled\n * @return errors An array of NO_ERROR for compatibility with Venus core tooling\n * @custom:event MarketEntered is emitted for each market on success\n * @custom:error ActionPaused error is thrown if entering any of the markets is paused\n * @custom:error MarketNotListed error is thrown if any of the markets is not listed\n * @custom:access Not restricted\n */\n function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\n uint256 len = vTokens.length;\n\n uint256[] memory results = new uint256[](len);\n for (uint256 i; i < len; ++i) {\n VToken vToken = VToken(vTokens[i]);\n\n _addToMarket(vToken, msg.sender);\n results[i] = NO_ERROR;\n }\n\n return results;\n }\n\n /**\n * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event MarketExited is emitted on success\n * @custom:error ActionPaused error is thrown if exiting the market is paused\n * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function exitMarket(address vTokenAddress) external override returns (uint256) {\n _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\n VToken vToken = VToken(vTokenAddress);\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\n (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\n\n /* Fail if the sender has a borrow balance */\n if (amountOwed != 0) {\n revert NonzeroBorrowBalance();\n }\n\n /* Fail if the sender is not permitted to redeem all of their tokens */\n _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\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 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 // load into memory for faster iteration\n VToken[] memory userAssetList = accountAssets[msg.sender];\n uint256 len = userAssetList.length;\n\n uint256 assetIndex = len;\n for (uint256 i; i < len; ++i) {\n if (userAssetList[i] == vToken) {\n assetIndex = i;\n break;\n }\n }\n\n // We *must* have found the asset in the list or our redundant data structure is broken\n assert(assetIndex < len);\n\n // copy last item in list to location of item to be removed, reduce length by 1\n VToken[] storage storedList = accountAssets[msg.sender];\n storedList[assetIndex] = storedList[storedList.length - 1];\n storedList.pop();\n\n emit MarketExited(vToken, msg.sender);\n\n return NO_ERROR;\n }\n\n /*** Policy Hooks ***/\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 * @custom:error ActionPaused error is thrown if supplying to this market is paused\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\n * @custom:access Not restricted\n */\n function preMintHook(\n address vToken,\n address minter,\n uint256 mintAmount\n ) external override {\n _checkActionPauseState(vToken, Action.MINT);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n uint256 supplyCap = supplyCaps[vToken];\n // Skipping the cap check for uncapped coins to save some gas\n if (supplyCap != type(uint256).max) {\n uint256 vTokenSupply = VToken(vToken).totalSupply();\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\n if (nextTotalSupply > supplyCap) {\n revert SupplyCapExceeded(vToken, supplyCap);\n }\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function preRedeemHook(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) external override {\n _checkActionPauseState(vToken, Action.REDEEM);\n\n _checkRedeemAllowed(vToken, redeemer, redeemTokens);\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\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 * @custom:error ActionPaused error is thrown if borrowing is paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\n * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\n */\n /// disable-eslint\n function preBorrowHook(\n address vToken,\n address borrower,\n uint256 borrowAmount\n ) external override {\n _checkActionPauseState(vToken, Action.BORROW);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n if (!markets[vToken].accountMembership[borrower]) {\n // only vTokens may call borrowAllowed if borrower not in market\n _checkSenderIs(vToken);\n\n // attempt to add borrower to the market or revert\n _addToMarket(VToken(msg.sender), borrower);\n }\n\n // Update the prices of tokens\n updatePrices(borrower);\n\n if (oracle.getUnderlyingPrice(vToken) == 0) {\n revert PriceError(address(vToken));\n }\n\n uint256 borrowCap = borrowCaps[vToken];\n // Skipping the cap check for uncapped coins to save some gas\n if (borrowCap != type(uint256).max) {\n uint256 totalBorrows = VToken(vToken).totalBorrows();\n uint256 badDebt = VToken(vToken).badDebt();\n uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\n if (nextTotalBorrows > borrowCap) {\n revert BorrowCapExceeded(vToken, borrowCap);\n }\n }\n\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n borrower,\n VToken(vToken),\n 0,\n borrowAmount,\n _getCollateralFactor\n );\n\n if (snapshot.shortfall > 0) {\n revert InsufficientLiquidity();\n }\n\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\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 borrower The account which would borrowed the asset\n * @custom:error ActionPaused error is thrown if repayments are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:access Not restricted\n */\n function preRepayHook(address vToken, address borrower) external override {\n _checkActionPauseState(vToken, Action.REPAY);\n\n oracle.updatePrice(vToken);\n\n if (!markets[vToken].isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\n rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\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 borrower The address of the borrower\n * @param repayAmount The amount of underlying being repaid\n * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\n * @custom:error ActionPaused error is thrown if liquidations are paused in this market\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\n * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\n * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\n * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n */\n function preLiquidateHook(\n address vTokenBorrowed,\n address vTokenCollateral,\n address borrower,\n uint256 repayAmount,\n bool skipLiquidityCheck\n ) external override {\n // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\n // If we want to pause liquidating to vTokenCollateral, we should pause\n // Action.SEIZE on it\n _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\n\n // Update the prices of tokens\n updatePrices(borrower);\n\n if (!markets[vTokenBorrowed].isListed) {\n revert MarketNotListed(address(vTokenBorrowed));\n }\n if (!markets[vTokenCollateral].isListed) {\n revert MarketNotListed(address(vTokenCollateral));\n }\n\n uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\n\n /* Allow accounts to be liquidated if the market is deprecated or it is a forced liquidation */\n if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {\n if (repayAmount > borrowBalance) {\n revert TooMuchRepay();\n }\n return;\n }\n\n /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral <= minLiquidatableCollateral) {\n /* The liquidator should use either liquidateAccount or healAccount */\n revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n /* The liquidator may not repay more than what is allowed by the closeFactor */\n uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\n if (repayAmount > maxClose) {\n revert TooMuchRepay();\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 seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\n * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\n * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\n * @custom:access Not restricted\n */\n function preSeizeHook(\n address vTokenCollateral,\n address seizerContract,\n address liquidator,\n address borrower\n ) external override {\n // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\n // If we want to pause liquidating vTokenBorrowed, we should pause\n // Action.LIQUIDATE on it\n _checkActionPauseState(vTokenCollateral, Action.SEIZE);\n\n Market storage market = markets[vTokenCollateral];\n\n if (!market.isListed) {\n revert MarketNotListed(vTokenCollateral);\n }\n\n if (seizerContract == address(this)) {\n // If Comptroller is the seizer, just check if collateral's comptroller\n // is equal to the current address\n if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\n revert ComptrollerMismatch();\n }\n } else {\n // If the seizer is not the Comptroller, check that the seizer is a\n // listed market, and that the markets' comptrollers match\n if (!markets[seizerContract].isListed) {\n revert MarketNotListed(seizerContract);\n }\n if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\n revert ComptrollerMismatch();\n }\n }\n\n if (!market.accountMembership[borrower]) {\n revert MarketNotCollateral(vTokenCollateral, borrower);\n }\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\n rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\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 * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function preTransferHook(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external override {\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 _checkRedeemAllowed(vToken, src, transferTokens);\n\n // Keep the flywheel moving\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\n rewardsDistributor.distributeSupplierRewardToken(vToken, src);\n rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\n }\n }\n\n /*** Pool-level operations ***/\n\n /**\n * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\n * borrows, and treats the rest of the debt as bad debt (for each market).\n * The sender has to repay a certain percentage of the debt, computed as\n * collateral / (borrows * liquidationIncentive).\n * @param user account to heal\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function healAccount(address user) external {\n VToken[] memory userAssets = accountAssets[user];\n uint256 userAssetsCount = userAssets.length;\n\n address liquidator = msg.sender;\n {\n ResilientOracleInterface oracle_ = oracle;\n // We need all user's markets to be fresh for the computations to be correct\n for (uint256 i; i < userAssetsCount; ++i) {\n userAssets[i].accrueInterest();\n oracle_.updatePrice(address(userAssets[i]));\n }\n }\n\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n // percentage = collateral / (borrows * liquidation incentive)\n Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\n Exp memory scaledBorrows = mul_(\n Exp({ mantissa: snapshot.borrows }),\n Exp({ mantissa: liquidationIncentiveMantissa })\n );\n\n Exp memory percentage = div_(collateral, scaledBorrows);\n if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\n revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\n }\n\n for (uint256 i; i < userAssetsCount; ++i) {\n VToken market = userAssets[i];\n\n (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\n uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\n\n // Seize the entire collateral\n if (tokens != 0) {\n market.seize(liquidator, user, tokens);\n }\n // Repay a certain percentage of the borrow, forgive the rest\n if (borrowBalance != 0) {\n market.healBorrow(liquidator, user, repaymentAmount);\n }\n }\n }\n\n /**\n * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\n * a predefined threshold, and the account collateral can be seized to cover all borrows. If\n * the collateral is higher than the threshold, use regular liquidations. If the collateral is\n * below the threshold, and the account is insolvent, use healAccount.\n * @param borrower the borrower address\n * @param orders an array of liquidation orders\n * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\n * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\n * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\n * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\n * @custom:access Not restricted\n */\n function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\n // We will accrue interest and update the oracle prices later during the liquidation\n\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\n\n if (snapshot.totalCollateral > minLiquidatableCollateral) {\n // You should use the regular vToken.liquidateBorrow(...) call\n revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\n }\n\n uint256 collateralToSeize = mul_ScalarTruncate(\n Exp({ mantissa: liquidationIncentiveMantissa }),\n snapshot.borrows\n );\n if (collateralToSeize >= snapshot.totalCollateral) {\n // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\n // and record bad debt.\n revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\n }\n\n if (snapshot.shortfall == 0) {\n revert InsufficientShortfall();\n }\n\n uint256 ordersCount = orders.length;\n\n _ensureMaxLoops(ordersCount / 2);\n\n for (uint256 i; i < ordersCount; ++i) {\n if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\n revert MarketNotListed(address(orders[i].vTokenBorrowed));\n }\n if (!markets[address(orders[i].vTokenCollateral)].isListed) {\n revert MarketNotListed(address(orders[i].vTokenCollateral));\n }\n\n LiquidationOrder calldata order = orders[i];\n order.vTokenBorrowed.forceLiquidateBorrow(\n msg.sender,\n borrower,\n order.repayAmount,\n order.vTokenCollateral,\n true\n );\n }\n\n VToken[] memory borrowMarkets = accountAssets[borrower];\n uint256 marketsCount = borrowMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\n require(borrowBalance == 0, \"Nonzero borrow balance after liquidation\");\n }\n }\n\n /**\n * @notice Sets the closeFactor to use when liquidating borrows\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\n * @custom:event Emits NewCloseFactor on success\n * @custom:access Controlled by AccessControlManager\n */\n function setCloseFactor(uint256 newCloseFactorMantissa) external {\n _checkAccessAllowed(\"setCloseFactor(uint256)\");\n require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \"Close factor greater than maximum close factor\");\n require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \"Close factor smaller than minimum close factor\");\n\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\n closeFactorMantissa = newCloseFactorMantissa;\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\n }\n\n /**\n * @notice Sets the collateralFactor for a market\n * @dev This function is restricted by the AccessControlManager\n * @param vToken The market to set the factor on\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\n * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\n * @custom:event Emits NewCollateralFactor when collateral factor is updated\n * and NewLiquidationThreshold when liquidation threshold is updated\n * @custom:error MarketNotListed error is thrown when the market is not listed\n * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\n * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\n * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\n * @custom:access Controlled by AccessControlManager\n */\n function setCollateralFactor(\n VToken vToken,\n uint256 newCollateralFactorMantissa,\n uint256 newLiquidationThresholdMantissa\n ) external {\n _checkAccessAllowed(\"setCollateralFactor(address,uint256,uint256)\");\n\n // Verify market is listed\n Market storage market = markets[address(vToken)];\n if (!market.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n // Check collateral factor <= 0.9\n if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\n revert InvalidCollateralFactor();\n }\n\n // Ensure that liquidation threshold <= 1\n if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\n revert InvalidLiquidationThreshold();\n }\n\n // Ensure that liquidation threshold >= CF\n if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\n revert InvalidLiquidationThreshold();\n }\n\n // If collateral factor != 0, fail if price == 0\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\n revert PriceError(address(vToken));\n }\n\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\n if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\n market.collateralFactorMantissa = newCollateralFactorMantissa;\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\n }\n\n uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\n if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\n market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\n emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\n }\n }\n\n /**\n * @notice Sets liquidationIncentive\n * @dev This function is restricted by the AccessControlManager\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\n * @custom:event Emits NewLiquidationIncentive on success\n * @custom:access Controlled by AccessControlManager\n */\n function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\n require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \"liquidation incentive should be greater than 1e18\");\n\n _checkAccessAllowed(\"setLiquidationIncentive(uint256)\");\n\n // Save current value for use in log\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\n\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\n /**\n * @notice Add the market to the markets mapping and set it as listed\n * @dev Only callable by the PoolRegistry\n * @param vToken The address of the market (token) to list\n * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\n * @custom:access Only PoolRegistry\n */\n function supportMarket(VToken vToken) external {\n _checkSenderIs(poolRegistry);\n\n if (markets[address(vToken)].isListed) {\n revert MarketAlreadyListed(address(vToken));\n }\n\n require(vToken.isVToken(), \"Comptroller: Invalid vToken\"); // Sanity check to make sure its really a VToken\n\n Market storage newMarket = markets[address(vToken)];\n newMarket.isListed = true;\n newMarket.collateralFactorMantissa = 0;\n newMarket.liquidationThresholdMantissa = 0;\n\n _addMarket(address(vToken));\n\n uint256 rewardDistributorsCount = rewardsDistributors.length;\n\n for (uint256 i; i < rewardDistributorsCount; ++i) {\n rewardsDistributors[i].initializeMarket(address(vToken));\n }\n\n emit MarketSupported(vToken);\n }\n\n /**\n * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\n * @dev This function is restricted by the AccessControlManager\n * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\n * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\n until the total borrows amount goes below the new borrow cap\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 type(uint256).max corresponds to unlimited borrowing.\n * @custom:access Controlled by AccessControlManager\n */\n function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\n _checkAccessAllowed(\"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 _ensureMaxLoops(numMarkets);\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 markets. Supply that brings total Supply to or above supply cap will revert.\n * @dev This function is restricted by the AccessControlManager\n * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\n * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\n until the total supplies amount goes below the new supply cap\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 type(uint256).max corresponds to unlimited supply.\n * @custom:access Controlled by AccessControlManager\n */\n function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\n _checkAccessAllowed(\"setMarketSupplyCaps(address[],uint256[])\");\n uint256 vTokensCount = vTokens.length;\n\n require(vTokensCount != 0, \"invalid number of markets\");\n require(vTokensCount == newSupplyCaps.length, \"invalid number of markets\");\n\n _ensureMaxLoops(vTokensCount);\n\n for (uint256 i; i < vTokensCount; ++i) {\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\n }\n }\n\n /**\n * @notice Pause/unpause specified actions\n * @dev This function is restricted by the AccessControlManager\n * @param marketsList Markets to pause/unpause the actions on\n * @param actionsList List of action ids to pause/unpause\n * @param paused The new paused state (true=paused, false=unpaused)\n * @custom:access Controlled by AccessControlManager\n */\n function setActionsPaused(\n VToken[] calldata marketsList,\n Action[] calldata actionsList,\n bool paused\n ) external {\n _checkAccessAllowed(\"setActionsPaused(address[],uint256[],bool)\");\n\n uint256 marketsCount = marketsList.length;\n uint256 actionsCount = actionsList.length;\n\n _ensureMaxLoops(marketsCount * actionsCount);\n\n for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\n for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\n _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\n }\n }\n }\n\n /**\n * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\n * will fail if the collateral amount is less than this threshold. Liquidators should use batch\n * operations like liquidateAccount or healAccount.\n * @dev This function is restricted by the AccessControlManager\n * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\n * @custom:access Controlled by AccessControlManager\n */\n function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\n _checkAccessAllowed(\"setMinLiquidatableCollateral(uint256)\");\n\n uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\n minLiquidatableCollateral = newMinLiquidatableCollateral;\n emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\n }\n\n /**\n * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\n * contracts with the same rewardToken, and there could be overlaping among them considering the last reward block\n * @dev Only callable by the admin\n * @param _rewardsDistributor Address of the RewardDistributor contract to add\n * @custom:access Only Governance\n * @custom:event Emits NewRewardsDistributor with distributor address\n */\n function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\n require(!rewardsDistributorExists[address(_rewardsDistributor)], \"already exists\");\n\n uint256 rewardsDistributorsLen = rewardsDistributors.length;\n _ensureMaxLoops(rewardsDistributorsLen + 1);\n\n rewardsDistributors.push(_rewardsDistributor);\n rewardsDistributorExists[address(_rewardsDistributor)] = true;\n\n uint256 marketsCount = allMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n _rewardsDistributor.initializeMarket(address(allMarkets[i]));\n }\n\n emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\n }\n\n /**\n * @notice Sets a new price oracle for the Comptroller\n * @dev Only callable by the admin\n * @param newOracle Address of the new price oracle to set\n * @custom:event Emits NewPriceOracle on success\n * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\n */\n function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\n ensureNonzeroAddress(address(newOracle));\n\n ResilientOracleInterface oldOracle = oracle;\n oracle = newOracle;\n emit NewPriceOracle(oldOracle, newOracle);\n }\n\n /**\n * @notice Set the for loop iteration limit to avoid DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Determine the current account liquidity with respect to liquidation threshold requirements\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\n * @param account The account get liquidity for\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Account liquidity in excess of liquidation threshold requirements,\n * @return shortfall Account shortfall below liquidation threshold requirements\n */\n function getAccountLiquidity(address account)\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\n }\n\n /**\n * @notice Determine the current account liquidity with respect to collateral requirements\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\n * @param account The account get liquidity for\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Account liquidity in excess of collateral requirements,\n * @return shortfall Account shortfall below collateral requirements\n */\n function getBorrowingPower(address account)\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\n }\n\n /**\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\n * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\n * @return shortfall Hypothetical account shortfall below collateral requirements\n */\n function getHypotheticalAccountLiquidity(\n address account,\n address vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n )\n external\n view\n returns (\n uint256 error,\n uint256 liquidity,\n uint256 shortfall\n )\n {\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n account,\n VToken(vTokenModify),\n redeemTokens,\n borrowAmount,\n _getCollateralFactor\n );\n return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\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 markets The list of market addresses\n */\n function getAllMarkets() external view override returns (VToken[] memory) {\n return allMarkets;\n }\n\n /**\n * @notice Check if a market is marked as listed (active)\n * @param vToken vToken Address for the market to check\n * @return listed True if listed otherwise false\n */\n function isMarketListed(VToken vToken) external view returns (bool) {\n return markets[address(vToken)].isListed;\n }\n\n /*** Assets You Are In ***/\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 list with the assets the account has entered\n */\n function getAssetsIn(address account) external view returns (VToken[] memory) {\n VToken[] memory assetsIn = accountAssets[account];\n\n return assetsIn;\n }\n\n /**\n * @notice Returns whether the given account is entered in a given market\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 market specified, 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 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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\n * @custom:error PriceError if the oracle returns an invalid price\n */\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view override returns (uint256 error, uint256 tokensToSeize) {\n /* Read oracle prices for borrowed and collateral markets */\n uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\n uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\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 uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\n uint256 seizeTokens;\n Exp memory numerator;\n Exp memory denominator;\n Exp memory ratio;\n\n numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\n ratio = div_(numerator, denominator);\n\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\n\n return (NO_ERROR, seizeTokens);\n }\n\n /**\n * @notice Returns reward speed given a vToken\n * @param vToken The vToken to get the reward speeds for\n * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\n */\n function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\n uint256 rewardsDistributorsLength = rewardsDistributors.length;\n rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\n for (uint256 i; i < rewardsDistributorsLength; ++i) {\n RewardsDistributor rewardsDistributor = rewardsDistributors[i];\n address rewardToken = address(rewardsDistributor.rewardToken());\n rewardSpeeds[i] = RewardSpeeds({\n rewardToken: rewardToken,\n supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\n borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\n });\n }\n return rewardSpeeds;\n }\n\n /**\n * @notice Return all reward distributors for this pool\n * @return Array of RewardDistributor addresses\n */\n function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\n return rewardsDistributors;\n }\n\n /**\n * @notice A marker method that returns true for a valid Comptroller contract\n * @return Always true\n */\n function isComptroller() external pure override returns (bool) {\n return true;\n }\n\n /**\n * @notice Update the prices of all the tokens associated with the provided account\n * @param account Address of the account to get associated tokens with\n */\n function updatePrices(address account) public {\n VToken[] memory vTokens = accountAssets[account];\n uint256 vTokensCount = vTokens.length;\n\n ResilientOracleInterface oracle_ = oracle;\n\n for (uint256 i; i < vTokensCount; ++i) {\n oracle_.updatePrice(address(vTokens[i]));\n }\n }\n\n /**\n * @notice Checks if a certain action is paused on a market\n * @param market vToken address\n * @param action Action to check\n * @return paused True if the action is paused otherwise false\n */\n function actionPaused(address market, Action action) public view returns (bool) {\n return _actionPaused[market][action];\n }\n\n /**\n * @notice Check if a vToken market has been deprecated\n * @dev All borrows in a deprecated vToken market can be immediately liquidated\n * @param vToken The market to check if deprecated\n * @return deprecated True if the given vToken market has been deprecated\n */\n function isDeprecated(VToken vToken) public view returns (bool) {\n return\n markets[address(vToken)].collateralFactorMantissa == 0 &&\n actionPaused(address(vToken), Action.BORROW) &&\n vToken.reserveFactorMantissa() == MANTISSA_ONE;\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 */\n function _addToMarket(VToken vToken, address borrower) internal {\n _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\n Market storage marketToJoin = markets[address(vToken)];\n\n if (!marketToJoin.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n if (marketToJoin.accountMembership[borrower]) {\n // already joined\n return;\n }\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\n /**\n * @notice Internal function to validate that a market hasn't already been added\n * and if it hasn't adds it\n * @param vToken The market to support\n */\n function _addMarket(address vToken) internal {\n uint256 marketsCount = allMarkets.length;\n\n for (uint256 i; i < marketsCount; ++i) {\n if (allMarkets[i] == VToken(vToken)) {\n revert MarketAlreadyListed(vToken);\n }\n }\n allMarkets.push(VToken(vToken));\n marketsCount = allMarkets.length;\n _ensureMaxLoops(marketsCount);\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 _setActionPaused(\n address market,\n Action action,\n bool paused\n ) internal {\n require(markets[market].isListed, \"cannot pause a market that is not listed\");\n _actionPaused[market][action] = paused;\n emit ActionPausedMarket(VToken(market), action, paused);\n }\n\n /**\n * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\n * @param vToken Address of the vTokens to redeem\n * @param redeemer Account redeeming the tokens\n * @param redeemTokens The number of tokens to redeem\n */\n function _checkRedeemAllowed(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) internal {\n Market storage market = markets[vToken];\n\n if (!market.isListed) {\n revert MarketNotListed(address(vToken));\n }\n\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\n if (!market.accountMembership[redeemer]) {\n return;\n }\n\n // Update the prices of tokens\n updatePrices(redeemer);\n\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\n AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\n redeemer,\n VToken(vToken),\n redeemTokens,\n 0,\n _getCollateralFactor\n );\n if (snapshot.shortfall > 0) {\n revert InsufficientLiquidity();\n }\n }\n\n /**\n * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\n * @param account The account to get the snapshot for\n * @param weight The function to compute the weight of the collateral – either collateral factor or\n * liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\n * without calculating accumulated interest.\n * @return snapshot Account liquidity snapshot\n */\n function _getCurrentLiquiditySnapshot(address account, function(VToken) internal view returns (Exp memory) weight)\n internal\n view\n returns (AccountLiquiditySnapshot memory snapshot)\n {\n return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\n }\n\n /**\n * @notice Determine what the supply/borrow balances 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 * @param weight The function to compute the weight of the collateral – either collateral factor or\n liquidation threshold. Accepts the address of the VToken and returns the weight\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\n * without calculating accumulated interest.\n * @return snapshot Account liquidity snapshot\n */\n function _getHypotheticalLiquiditySnapshot(\n address account,\n VToken vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount,\n function(VToken) internal view returns (Exp memory) weight\n ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\n // For each asset the account is in\n VToken[] memory assets = accountAssets[account];\n uint256 assetsCount = assets.length;\n\n for (uint256 i; i < assetsCount; ++i) {\n VToken asset = assets[i];\n\n // Read the balances and exchange rate from the vToken\n (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\n asset,\n account\n );\n\n // Get the normalized price of the asset\n Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\n\n // Pre-compute conversion factors from vTokens -> usd\n Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\n Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\n\n // weightedCollateral += weightedVTokenPrice * vTokenBalance\n snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\n weightedVTokenPrice,\n vTokenBalance,\n snapshot.weightedCollateral\n );\n\n // totalCollateral += vTokenPrice * vTokenBalance\n snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\n\n // borrows += oraclePrice * borrowBalance\n snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\n\n // Calculate effects of interacting with vTokenModify\n if (asset == vTokenModify) {\n // redeem effect\n // effects += tokensToDenom * redeemTokens\n snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\n\n // borrow effect\n // effects += oraclePrice * borrowAmount\n snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\n }\n }\n\n uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\n // These are safe, as the underflow condition is checked first\n unchecked {\n if (snapshot.weightedCollateral > borrowPlusEffects) {\n snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\n snapshot.shortfall = 0;\n } else {\n snapshot.liquidity = 0;\n snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\n }\n }\n\n return snapshot;\n }\n\n /**\n * @dev Retrieves price from oracle for an asset and checks it is nonzero\n * @param asset Address for asset to query price\n * @return Underlying price\n */\n function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\n uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\n if (oraclePriceMantissa == 0) {\n revert PriceError(address(asset));\n }\n return oraclePriceMantissa;\n }\n\n /**\n * @dev Return collateral factor for a market\n * @param asset Address for asset\n * @return Collateral factor as exponential\n */\n function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\n return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\n }\n\n /**\n * @dev Retrieves liquidation threshold for a market as an exponential\n * @param asset Address for asset to liquidation threshold\n * @return Liquidation threshold as exponential\n */\n function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\n return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\n }\n\n /**\n * @dev Returns supply and borrow balances of user in vToken, reverts on failure\n * @param vToken Market to query\n * @param user Account address\n * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\n * @return borrowBalance Borrowed amount, including the interest\n * @return exchangeRateMantissa Stored exchange rate\n */\n function _safeGetAccountSnapshot(VToken vToken, address user)\n internal\n view\n returns (\n uint256 vTokenBalance,\n uint256 borrowBalance,\n uint256 exchangeRateMantissa\n )\n {\n uint256 err;\n (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\n if (err != 0) {\n revert SnapshotError(address(vToken), user);\n }\n return (vTokenBalance, borrowBalance, exchangeRateMantissa);\n }\n\n /// @notice Reverts if the call is not from expectedSender\n /// @param expectedSender Expected transaction sender\n function _checkSenderIs(address expectedSender) internal view {\n if (msg.sender != expectedSender) {\n revert UnexpectedSender(expectedSender, msg.sender);\n }\n }\n\n /// @notice Reverts if a certain action is paused on a market\n /// @param market Market to check\n /// @param action Action to check\n function _checkActionPauseState(address market, Action action) private view {\n if (actionPaused(market, action)) {\n revert ActionPaused(market, action);\n }\n }\n}\n" + }, + "contracts/ComptrollerInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\n\n/**\n * @title ComptrollerInterface\n * @author Venus\n * @notice Interface implemented by the `Comptroller` contract.\n */\ninterface ComptrollerInterface {\n /*** Assets You Are In ***/\n\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\n\n function exitMarket(address vToken) external returns (uint256);\n\n /*** Policy Hooks ***/\n\n function preMintHook(\n address vToken,\n address minter,\n uint256 mintAmount\n ) external;\n\n function preRedeemHook(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) external;\n\n function preBorrowHook(\n address vToken,\n address borrower,\n uint256 borrowAmount\n ) external;\n\n function preRepayHook(address vToken, address borrower) external;\n\n function preLiquidateHook(\n address vTokenBorrowed,\n address vTokenCollateral,\n address borrower,\n uint256 repayAmount,\n bool skipLiquidityCheck\n ) external;\n\n function preSeizeHook(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower\n ) external;\n\n function preTransferHook(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external;\n\n function isComptroller() external view returns (bool);\n\n /*** Liquidity/Liquidation Calculations ***/\n\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 repayAmount\n ) external view returns (uint256, uint256);\n\n function getAllMarkets() external view returns (VToken[] memory);\n}\n\n/**\n * @title ComptrollerViewInterface\n * @author Venus\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\n */\ninterface ComptrollerViewInterface {\n function markets(address) external view returns (bool, uint256);\n\n function oracle() external view returns (ResilientOracleInterface);\n\n function getAssetsIn(address) external view returns (VToken[] memory);\n\n function closeFactorMantissa() external view returns (uint256);\n\n function liquidationIncentiveMantissa() external view returns (uint256);\n\n function minLiquidatableCollateral() external view returns (uint256);\n\n function getRewardDistributors() external view returns (RewardsDistributor[] memory);\n\n function getAllMarkets() external view returns (VToken[] memory);\n\n function borrowCaps(address) external view returns (uint256);\n\n function supplyCaps(address) external view returns (uint256);\n}\n" + }, + "contracts/ComptrollerStorage.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { VToken } from \"./VToken.sol\";\nimport { RewardsDistributor } from \"./Rewards/RewardsDistributor.sol\";\n\n/**\n * @title ComptrollerStorage\n * @author Venus\n * @notice Storage layout for the `Comptroller` contract.\n */\ncontract ComptrollerStorage {\n struct LiquidationOrder {\n VToken vTokenCollateral;\n VToken vTokenBorrowed;\n uint256 repayAmount;\n }\n\n struct AccountLiquiditySnapshot {\n uint256 totalCollateral;\n uint256 weightedCollateral;\n uint256 borrows;\n uint256 effects;\n uint256 liquidity;\n uint256 shortfall;\n }\n\n struct RewardSpeeds {\n address rewardToken;\n uint256 supplySpeed;\n uint256 borrowSpeed;\n }\n\n struct Market {\n // Whether or not this market is listed\n bool isListed;\n // 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 uint256 collateralFactorMantissa;\n // Multiplier representing the collateralization after which the borrow is eligible\n // for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\n // value. Must be between 0 and collateral factor, stored as a mantissa.\n uint256 liquidationThresholdMantissa;\n // Per-market mapping of \"accounts in this asset\"\n mapping(address => bool) accountMembership;\n }\n\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 /**\n * @notice Oracle which gives the price of any given asset\n */\n ResilientOracleInterface 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 Per-account mapping of \"assets you are in\"\n */\n mapping(address => VToken[]) public accountAssets;\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 /// @notice A list of all markets\n VToken[] public allMarkets;\n\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\n mapping(address => uint256) public borrowCaps;\n\n /// @notice Minimal collateral required for regular (non-batch) liquidations\n uint256 public minLiquidatableCollateral;\n\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\n mapping(address => uint256) public supplyCaps;\n\n /// @notice True if a certain action is paused on a certain market\n mapping(address => mapping(Action => bool)) internal _actionPaused;\n\n // List of Reward Distributors added\n RewardsDistributor[] internal rewardsDistributors;\n\n // Used to check if rewards distributor is added\n mapping(address => bool) internal rewardsDistributorExists;\n\n uint256 internal constant NO_ERROR = 0;\n\n // closeFactorMantissa must be strictly greater than this value\n uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\n\n // closeFactorMantissa must not exceed this value\n uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\n\n // No collateralFactorMantissa may exceed this value\n uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.9e18; // 0.9\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[50] private __gap;\n}\n" + }, + "contracts/ErrorReporter.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title TokenErrorReporter\n * @author Venus\n * @notice Errors that can be thrown by the `VToken` contract.\n */\ncontract TokenErrorReporter {\n uint256 public constant NO_ERROR = 0; // support legacy return codes\n\n error TransferNotAllowed();\n\n error MintFreshnessCheck();\n\n error RedeemFreshnessCheck();\n error RedeemTransferOutNotPossible();\n\n error BorrowFreshnessCheck();\n error BorrowCashNotAvailable();\n\n error RepayBorrowFreshnessCheck();\n\n error HealBorrowUnauthorized();\n error ForceLiquidateBorrowUnauthorized();\n\n error LiquidateFreshnessCheck();\n error LiquidateCollateralFreshnessCheck();\n error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\n error LiquidateLiquidatorIsBorrower();\n error LiquidateCloseAmountIsZero();\n error LiquidateCloseAmountIsUintMax();\n\n error LiquidateSeizeLiquidatorIsBorrower();\n\n error ProtocolSeizeShareTooBig();\n\n error SetReserveFactorFreshCheck();\n error SetReserveFactorBoundsCheck();\n\n error AddReservesFactorFreshCheck(uint256 actualAddAmount);\n\n error ReduceReservesFreshCheck();\n error ReduceReservesCashNotAvailable();\n error ReduceReservesCashValidation();\n\n error SetInterestRateModelFreshCheck();\n}\n" + }, + "contracts/ExponentialNoError.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \"./lib/constants.sol\";\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 struct Exp {\n uint256 mantissa;\n }\n\n struct Double {\n uint256 mantissa;\n }\n\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\n uint256 internal constant DOUBLE_SCALE = 1e36;\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\n\n /**\n * @dev Truncates the given exp to a whole number value.\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\n */\n function truncate(Exp memory exp) internal pure returns (uint256) {\n // Note: We are not using careful math here as we're performing a division that cannot fail\n return exp.mantissa / EXP_SCALE;\n }\n\n /**\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\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 // solhint-disable-next-line func-name-mixedcase\n function mul_ScalarTruncateAddUInt(\n Exp memory a,\n uint256 scalar,\n uint256 addend\n ) internal pure returns (uint256) {\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 function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\n require(n <= type(uint224).max, errorMessage);\n return uint224(n);\n }\n\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\n require(n <= type(uint32).max, 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_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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_(uint256 a, uint256 b) internal pure returns (uint256) {\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) / EXP_SCALE });\n }\n\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\n return mul_(a, b.mantissa) / EXP_SCALE;\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) / DOUBLE_SCALE });\n }\n\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\n }\n\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\n }\n\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\n return div_(mul_(a, EXP_SCALE), 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, DOUBLE_SCALE), b.mantissa) });\n }\n\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\n }\n\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\n }\n}\n" + }, + "contracts/InterestRateModel.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title Compound's InterestRateModel Interface\n * @author Compound\n */\nabstract contract InterestRateModel {\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 amount of reserves the market has\n * @param badDebt The amount of badDebt in the market\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\n */\n function getBorrowRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) external view virtual returns (uint256);\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 amount of reserves the market has\n * @param reserveFactorMantissa The current reserve factor the market has\n * @param badDebt The amount of badDebt in the market\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\n */\n function getSupplyRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 reserveFactorMantissa,\n uint256 badDebt\n ) external view virtual returns (uint256);\n\n /**\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\n * @return Always true\n */\n function isInterestRateModel() external pure virtual returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/IPancakeswapV2Router.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\ninterface IPancakeswapV2Router {\n function swapExactTokensForTokens(\n uint256 amountIn,\n uint256 amountOutMin,\n address[] calldata path,\n address to,\n uint256 deadline\n ) external returns (uint256[] memory amounts);\n}\n" + }, + "contracts/Lens/PoolLens.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { RewardsDistributor } from \"../Rewards/RewardsDistributor.sol\";\n\n/**\n * @title PoolLens\n * @author Venus\n * @notice The `PoolLens` contract is designed to retrieve important information for each registered pool. A list of essential information\n * for all pools within the lending protocol can be acquired through the function `getAllPools()`. Additionally, the following records can be\n * looked up for specific pools and markets:\n- the vToken balance of a given user;\n- the pool data (oracle address, associated vToken, liquidation incentive, etc) of a pool via its associated comptroller address;\n- the vToken address in a pool for a given asset;\n- a list of all pools that support an asset;\n- the underlying asset price of a vToken;\n- the metadata (exchange/borrow/supply rate, total supply, collateral factor, etc) of any vToken.\n */\ncontract PoolLens is ExponentialNoError {\n /**\n * @dev Struct for PoolDetails.\n */\n struct PoolData {\n string name;\n address creator;\n address comptroller;\n uint256 blockPosted;\n uint256 timestampPosted;\n string category;\n string logoURL;\n string description;\n address priceOracle;\n uint256 closeFactor;\n uint256 liquidationIncentive;\n uint256 minLiquidatableCollateral;\n VTokenMetadata[] vTokens;\n }\n\n /**\n * @dev Struct for VToken.\n */\n struct VTokenMetadata {\n address vToken;\n uint256 exchangeRateCurrent;\n uint256 supplyRatePerBlock;\n uint256 borrowRatePerBlock;\n uint256 reserveFactorMantissa;\n uint256 supplyCaps;\n uint256 borrowCaps;\n uint256 totalBorrows;\n uint256 totalReserves;\n uint256 totalSupply;\n uint256 totalCash;\n bool isListed;\n uint256 collateralFactorMantissa;\n address underlyingAssetAddress;\n uint256 vTokenDecimals;\n uint256 underlyingDecimals;\n }\n\n /**\n * @dev Struct for VTokenBalance.\n */\n struct VTokenBalances {\n address vToken;\n uint256 balanceOf;\n uint256 borrowBalanceCurrent;\n uint256 balanceOfUnderlying;\n uint256 tokenBalance;\n uint256 tokenAllowance;\n }\n\n /**\n * @dev Struct for underlyingPrice of VToken.\n */\n struct VTokenUnderlyingPrice {\n address vToken;\n uint256 underlyingPrice;\n }\n\n /**\n * @dev Struct with pending reward info for a market.\n */\n struct PendingReward {\n address vTokenAddress;\n uint256 amount;\n }\n\n /**\n * @dev Struct with reward distribution totals for a single reward token and distributor.\n */\n struct RewardSummary {\n address distributorAddress;\n address rewardTokenAddress;\n uint256 totalRewards;\n PendingReward[] pendingRewards;\n }\n\n /**\n * @dev Struct used in RewardDistributor to save last updated market state.\n */\n struct RewardTokenState {\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\n uint224 index;\n // The block number the index was last updated at\n uint32 block;\n // The block number at which to stop rewards\n uint32 lastRewardingBlock;\n }\n\n /**\n * @dev Struct with bad debt of a market denominated\n */\n struct BadDebt {\n address vTokenAddress;\n uint256 badDebtUsd;\n }\n\n /**\n * @dev Struct with bad debt total denominated in usd for a pool and an array of BadDebt structs for each market\n */\n struct BadDebtSummary {\n address comptroller;\n uint256 totalBadDebtUsd;\n BadDebt[] badDebts;\n }\n\n /**\n * @notice Queries the user's supply/borrow balances in vTokens\n * @param vTokens The list of vToken addresses\n * @param account The user Account\n * @return A list of structs containing balances data\n */\n function vTokenBalancesAll(VToken[] calldata vTokens, address account) external returns (VTokenBalances[] memory) {\n uint256 vTokenCount = vTokens.length;\n VTokenBalances[] memory res = new VTokenBalances[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenBalances(vTokens[i], account);\n }\n return res;\n }\n\n /**\n * @notice Queries all pools with addtional details for each of them\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @return Arrays of all Venus pools' data\n */\n function getAllPools(address poolRegistryAddress) external view returns (PoolData[] memory) {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n PoolRegistry.VenusPool[] memory venusPools = poolRegistryInterface.getAllPools();\n uint256 poolLength = venusPools.length;\n\n PoolData[] memory poolDataItems = new PoolData[](poolLength);\n\n for (uint256 i; i < poolLength; ++i) {\n PoolRegistry.VenusPool memory venusPool = venusPools[i];\n PoolData memory poolData = getPoolDataFromVenusPool(poolRegistryAddress, venusPool);\n poolDataItems[i] = poolData;\n }\n\n return poolDataItems;\n }\n\n /**\n * @notice Queries the details of a pool identified by Comptroller address\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param comptroller The Comptroller implementation address\n * @return PoolData structure containing the details of the pool\n */\n function getPoolByComptroller(address poolRegistryAddress, address comptroller)\n external\n view\n returns (PoolData memory)\n {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return getPoolDataFromVenusPool(poolRegistryAddress, poolRegistryInterface.getPoolByComptroller(comptroller));\n }\n\n /**\n * @notice Returns vToken holding the specified underlying asset in the specified pool\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param comptroller The pool comptroller\n * @param asset The underlyingAsset of VToken\n * @return Address of the vToken\n */\n function getVTokenForAsset(\n address poolRegistryAddress,\n address comptroller,\n address asset\n ) external view returns (address) {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return poolRegistryInterface.getVTokenForAsset(comptroller, asset);\n }\n\n /**\n * @notice Returns all pools that support the specified underlying asset\n * @param poolRegistryAddress The address of the PoolRegistry contract\n * @param asset The underlying asset of vToken\n * @return A list of Comptroller contracts\n */\n function getPoolsSupportedByAsset(address poolRegistryAddress, address asset)\n external\n view\n returns (address[] memory)\n {\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n return poolRegistryInterface.getPoolsSupportedByAsset(asset);\n }\n\n /**\n * @notice Returns the price data for the underlying assets of the specified vTokens\n * @param vTokens The list of vToken addresses\n * @return An array containing the price data for each asset\n */\n function vTokenUnderlyingPriceAll(VToken[] calldata vTokens)\n external\n view\n returns (VTokenUnderlyingPrice[] memory)\n {\n uint256 vTokenCount = vTokens.length;\n VTokenUnderlyingPrice[] memory res = new VTokenUnderlyingPrice[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenUnderlyingPrice(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Returns the pending rewards for a user for a given pool.\n * @param account The user account.\n * @param comptrollerAddress address\n * @return Pending rewards array\n */\n function getPendingRewards(address account, address comptrollerAddress)\n external\n view\n returns (RewardSummary[] memory)\n {\n VToken[] memory markets = ComptrollerInterface(comptrollerAddress).getAllMarkets();\n RewardsDistributor[] memory rewardsDistributors = ComptrollerViewInterface(comptrollerAddress)\n .getRewardDistributors();\n RewardSummary[] memory rewardSummary = new RewardSummary[](rewardsDistributors.length);\n for (uint256 i; i < rewardsDistributors.length; ++i) {\n RewardSummary memory reward;\n reward.distributorAddress = address(rewardsDistributors[i]);\n reward.rewardTokenAddress = address(rewardsDistributors[i].rewardToken());\n reward.totalRewards = rewardsDistributors[i].rewardTokenAccrued(account);\n reward.pendingRewards = _calculateNotDistributedAwards(account, markets, rewardsDistributors[i]);\n rewardSummary[i] = reward;\n }\n return rewardSummary;\n }\n\n /**\n * @notice Returns a summary of a pool's bad debt broken down by market\n *\n * @param comptrollerAddress Address of the comptroller\n *\n * @return badDebtSummary A struct with comptroller address, total bad debut denominated in usd, and\n * a break down of bad debt by market\n */\n function getPoolBadDebt(address comptrollerAddress) external view returns (BadDebtSummary memory) {\n uint256 totalBadDebtUsd;\n\n // Get every market in the pool\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);\n VToken[] memory markets = comptroller.getAllMarkets();\n ResilientOracleInterface priceOracle = comptroller.oracle();\n\n BadDebt[] memory badDebts = new BadDebt[](markets.length);\n\n BadDebtSummary memory badDebtSummary;\n badDebtSummary.comptroller = comptrollerAddress;\n badDebtSummary.badDebts = badDebts;\n\n // // Calculate the bad debt is USD per market\n for (uint256 i; i < markets.length; ++i) {\n BadDebt memory badDebt;\n badDebt.vTokenAddress = address(markets[i]);\n badDebt.badDebtUsd =\n (VToken(address(markets[i])).badDebt() * priceOracle.getUnderlyingPrice(address(markets[i]))) /\n EXP_SCALE;\n badDebtSummary.badDebts[i] = badDebt;\n totalBadDebtUsd = totalBadDebtUsd + badDebt.badDebtUsd;\n }\n\n badDebtSummary.totalBadDebtUsd = totalBadDebtUsd;\n\n return badDebtSummary;\n }\n\n /**\n * @notice Queries the user's supply/borrow balances in the specified vToken\n * @param vToken vToken address\n * @param account The user Account\n * @return A struct containing the balances data\n */\n function vTokenBalances(VToken vToken, address account) public returns (VTokenBalances memory) {\n uint256 balanceOf = vToken.balanceOf(account);\n uint256 borrowBalanceCurrent = vToken.borrowBalanceCurrent(account);\n uint256 balanceOfUnderlying = vToken.balanceOfUnderlying(account);\n uint256 tokenBalance;\n uint256 tokenAllowance;\n\n IERC20 underlying = IERC20(vToken.underlying());\n tokenBalance = underlying.balanceOf(account);\n tokenAllowance = underlying.allowance(account, address(vToken));\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 Queries additional information for the pool\n * @param poolRegistryAddress Address of the PoolRegistry\n * @param venusPool The VenusPool Object from PoolRegistry\n * @return Enriched PoolData\n */\n function getPoolDataFromVenusPool(address poolRegistryAddress, PoolRegistry.VenusPool memory venusPool)\n public\n view\n returns (PoolData memory)\n {\n // Get tokens in the Pool\n ComptrollerInterface comptrollerInstance = ComptrollerInterface(venusPool.comptroller);\n\n VToken[] memory vTokens = comptrollerInstance.getAllMarkets();\n\n VTokenMetadata[] memory vTokenMetadataItems = vTokenMetadataAll(vTokens);\n\n PoolRegistryInterface poolRegistryInterface = PoolRegistryInterface(poolRegistryAddress);\n\n PoolRegistry.VenusPoolMetaData memory venusPoolMetaData = poolRegistryInterface.getVenusPoolMetadata(\n venusPool.comptroller\n );\n\n ComptrollerViewInterface comptrollerViewInstance = ComptrollerViewInterface(venusPool.comptroller);\n\n PoolData memory poolData = PoolData({\n name: venusPool.name,\n creator: venusPool.creator,\n comptroller: venusPool.comptroller,\n blockPosted: venusPool.blockPosted,\n timestampPosted: venusPool.timestampPosted,\n category: venusPoolMetaData.category,\n logoURL: venusPoolMetaData.logoURL,\n description: venusPoolMetaData.description,\n vTokens: vTokenMetadataItems,\n priceOracle: address(comptrollerViewInstance.oracle()),\n closeFactor: comptrollerViewInstance.closeFactorMantissa(),\n liquidationIncentive: comptrollerViewInstance.liquidationIncentiveMantissa(),\n minLiquidatableCollateral: comptrollerViewInstance.minLiquidatableCollateral()\n });\n\n return poolData;\n }\n\n /**\n * @notice Returns the metadata of VToken\n * @param vToken The address of vToken\n * @return VTokenMetadata struct\n */\n function vTokenMetadata(VToken vToken) public view returns (VTokenMetadata memory) {\n uint256 exchangeRateCurrent = vToken.exchangeRateStored();\n address comptrollerAddress = address(vToken.comptroller());\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);\n (bool isListed, uint256 collateralFactorMantissa) = comptroller.markets(address(vToken));\n\n address underlyingAssetAddress = vToken.underlying();\n uint256 underlyingDecimals = IERC20Metadata(underlyingAssetAddress).decimals();\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 supplyCaps: comptroller.supplyCaps(address(vToken)),\n borrowCaps: comptroller.borrowCaps(address(vToken)),\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 });\n }\n\n /**\n * @notice Returns the metadata of all VTokens\n * @param vTokens The list of vToken addresses\n * @return An array of VTokenMetadata structs\n */\n function vTokenMetadataAll(VToken[] memory vTokens) public view returns (VTokenMetadata[] memory) {\n uint256 vTokenCount = vTokens.length;\n VTokenMetadata[] memory res = new VTokenMetadata[](vTokenCount);\n for (uint256 i; i < vTokenCount; ++i) {\n res[i] = vTokenMetadata(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Returns the price data for the underlying asset of the specified vToken\n * @param vToken vToken address\n * @return The price data for each asset\n */\n function vTokenUnderlyingPrice(VToken vToken) public view returns (VTokenUnderlyingPrice memory) {\n ComptrollerViewInterface comptroller = ComptrollerViewInterface(address(vToken.comptroller()));\n ResilientOracleInterface priceOracle = comptroller.oracle();\n\n return\n VTokenUnderlyingPrice({\n vToken: address(vToken),\n underlyingPrice: priceOracle.getUnderlyingPrice(address(vToken))\n });\n }\n\n function _calculateNotDistributedAwards(\n address account,\n VToken[] memory markets,\n RewardsDistributor rewardsDistributor\n ) internal view returns (PendingReward[] memory) {\n PendingReward[] memory pendingRewards = new PendingReward[](markets.length);\n for (uint256 i; i < markets.length; ++i) {\n // Market borrow and supply state we will modify update in-memory, in order to not modify storage\n RewardTokenState memory borrowState;\n (borrowState.index, borrowState.block, borrowState.lastRewardingBlock) = rewardsDistributor\n .rewardTokenBorrowState(address(markets[i]));\n RewardTokenState memory supplyState;\n (supplyState.index, supplyState.block, supplyState.lastRewardingBlock) = rewardsDistributor\n .rewardTokenSupplyState(address(markets[i]));\n Exp memory marketBorrowIndex = Exp({ mantissa: markets[i].borrowIndex() });\n\n // Update market supply and borrow index in-memory\n updateMarketBorrowIndex(address(markets[i]), rewardsDistributor, borrowState, marketBorrowIndex);\n updateMarketSupplyIndex(address(markets[i]), rewardsDistributor, supplyState);\n\n // Calculate pending rewards\n uint256 borrowReward = calculateBorrowerReward(\n address(markets[i]),\n rewardsDistributor,\n account,\n borrowState,\n marketBorrowIndex\n );\n uint256 supplyReward = calculateSupplierReward(\n address(markets[i]),\n rewardsDistributor,\n account,\n supplyState\n );\n\n PendingReward memory pendingReward;\n pendingReward.vTokenAddress = address(markets[i]);\n pendingReward.amount = borrowReward + supplyReward;\n pendingRewards[i] = pendingReward;\n }\n return pendingRewards;\n }\n\n function updateMarketBorrowIndex(\n address vToken,\n RewardsDistributor rewardsDistributor,\n RewardTokenState memory borrowState,\n Exp memory marketBorrowIndex\n ) internal view {\n uint256 borrowSpeed = rewardsDistributor.rewardTokenBorrowSpeeds(vToken);\n uint256 blockNumber = block.number;\n\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\n blockNumber = borrowState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(blockNumber, uint256(borrowState.block));\n if (deltaBlocks > 0 && borrowSpeed > 0) {\n // Remove the total earned interest rate since the opening of the market from total borrows\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint256 tokensAccrued = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount > 0 ? fraction(tokensAccrued, 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 function updateMarketSupplyIndex(\n address vToken,\n RewardsDistributor rewardsDistributor,\n RewardTokenState memory supplyState\n ) internal view {\n uint256 supplySpeed = rewardsDistributor.rewardTokenSupplySpeeds(vToken);\n uint256 blockNumber = block.number;\n\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\n blockNumber = supplyState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(blockNumber, uint256(supplyState.block));\n if (deltaBlocks > 0 && supplySpeed > 0) {\n uint256 supplyTokens = VToken(vToken).totalSupply();\n uint256 tokensAccrued = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens > 0 ? fraction(tokensAccrued, 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 function calculateBorrowerReward(\n address vToken,\n RewardsDistributor rewardsDistributor,\n address borrower,\n RewardTokenState memory borrowState,\n Exp memory marketBorrowIndex\n ) internal view returns (uint256) {\n Double memory borrowIndex = Double({ mantissa: borrowState.index });\n Double memory borrowerIndex = Double({\n mantissa: rewardsDistributor.rewardTokenBorrowerIndex(vToken, borrower)\n });\n if (borrowerIndex.mantissa == 0 && borrowIndex.mantissa >= rewardsDistributor.INITIAL_INDEX()) {\n // Covers the case where users borrowed tokens before the market's borrow state index was set\n borrowerIndex.mantissa = rewardsDistributor.INITIAL_INDEX();\n }\n Double memory deltaIndex = sub_(borrowIndex, borrowerIndex);\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\n return borrowerDelta;\n }\n\n function calculateSupplierReward(\n address vToken,\n RewardsDistributor rewardsDistributor,\n address supplier,\n RewardTokenState memory supplyState\n ) internal view returns (uint256) {\n Double memory supplyIndex = Double({ mantissa: supplyState.index });\n Double memory supplierIndex = Double({\n mantissa: rewardsDistributor.rewardTokenSupplierIndex(vToken, supplier)\n });\n if (supplierIndex.mantissa == 0 && supplyIndex.mantissa >= rewardsDistributor.INITIAL_INDEX()) {\n // Covers the case where users supplied tokens before the market's supply state index was set\n supplierIndex.mantissa = rewardsDistributor.INITIAL_INDEX();\n }\n Double memory deltaIndex = sub_(supplyIndex, supplierIndex);\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\n return supplierDelta;\n }\n}\n" + }, + "contracts/lib/ApproveOrRevert.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\nlibrary ApproveOrRevert {\n /// @notice Thrown if a contract is unable to approve a transfer\n error ApproveFailed();\n\n /// @notice Approves a transfer, ensuring that it is successful. This function supports non-compliant\n /// tokens like the ones that don't return a boolean value on success. Thus, such approve call supports\n /// three different kinds of tokens:\n /// * Compliant tokens that revert on failure\n /// * Compliant tokens that return false on failure\n /// * Non-compliant tokens that don't return a value\n /// @param token The contract address of the token which will be transferred\n /// @param spender The spender contract address\n /// @param amount The value of the transfer\n function approveOrRevert(\n IERC20Upgradeable token,\n address spender,\n uint256 amount\n ) internal {\n bytes memory callData = abi.encodeCall(token.approve, (spender, amount));\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory result) = address(token).call(callData);\n\n if (!success || (result.length != 0 && !abi.decode(result, (bool)))) {\n revert ApproveFailed();\n }\n }\n}\n" + }, + "contracts/lib/constants.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/// @dev The approximate number of blocks per year that is assumed by the interest rate model\nuint256 constant BLOCKS_PER_YEAR = 10_512_000;\n\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\nuint256 constant EXP_SCALE = 1e18;\n\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\nuint256 constant MANTISSA_ONE = EXP_SCALE;\n" + }, + "contracts/lib/TokenDebtTracker.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.13;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\n/**\n * @title TokenDebtTracker\n * @author Venus\n * @notice TokenDebtTracker is an abstract contract that handles transfers _out_ of the inheriting contract.\n * If there is an error transferring out (due to any reason, e.g. the token contract restricted the user from\n * receiving incoming transfers), the amount is recorded as a debt that can be claimed later.\n * @dev Note that the inheriting contract keeps some amount of users' tokens on its balance, so be careful when\n * using balanceOf(address(this))!\n */\nabstract contract TokenDebtTracker is Initializable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /**\n * @notice Mapping (IERC20Upgradeable token => (address user => uint256 amount)).\n * Tracks failed transfers: when a token transfer fails, we record the\n * amount of the transfer, so that the user can redeem this debt later.\n */\n mapping(IERC20Upgradeable => mapping(address => uint256)) public tokenDebt;\n\n /**\n * @notice Mapping (IERC20Upgradeable token => uint256 amount) shows how many\n * tokens the contract owes to all users. This is useful for accounting to\n * understand how much of balanceOf(address(this)) is already owed to users.\n */\n mapping(IERC20Upgradeable => uint256) public totalTokenDebt;\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 * @notice Emitted when the contract's debt to the user is increased due to a failed transfer\n * @param token Token address\n * @param user User address\n * @param amount The amount of debt added\n */\n event TokenDebtAdded(address indexed token, address indexed user, uint256 amount);\n\n /**\n * @notice Emitted when a user claims tokens that the contract owes them\n * @param token Token address\n * @param user User address\n * @param amount The amount transferred\n */\n event TokenDebtClaimed(address indexed token, address indexed user, uint256 amount);\n\n /**\n * @notice Thrown if the user tries to claim more tokens than they are owed\n * @param token The token the user is trying to claim\n * @param owedAmount The amount of tokens the contract owes to the user\n * @param amount The amount of tokens the user is trying to claim\n */\n error InsufficientDebt(address token, address user, uint256 owedAmount, uint256 amount);\n\n /**\n * @notice Thrown if trying to transfer more tokens than the contract currently has\n * @param token The token the contract is trying to transfer\n * @param recipient The recipient of the transfer\n * @param amount The amount of tokens the contract is trying to transfer\n * @param availableBalance The amount of tokens the contract currently has\n */\n error InsufficientBalance(address token, address recipient, uint256 amount, uint256 availableBalance);\n\n /**\n * @notice Transfers the tokens we owe to msg.sender, if any\n * @param token The token to claim\n * @param amount_ The amount of tokens to claim (or max uint256 to claim all)\n * @custom:error InsufficientDebt The contract doesn't have enough debt to the user\n */\n function claimTokenDebt(IERC20Upgradeable token, uint256 amount_) external {\n uint256 owedAmount = tokenDebt[token][msg.sender];\n uint256 amount = (amount_ == type(uint256).max ? owedAmount : amount_);\n if (amount > owedAmount) {\n revert InsufficientDebt(address(token), msg.sender, owedAmount, amount);\n }\n unchecked {\n // Safe because we revert if amount > owedAmount above\n tokenDebt[token][msg.sender] = owedAmount - amount;\n }\n totalTokenDebt[token] -= amount;\n emit TokenDebtClaimed(address(token), msg.sender, amount);\n token.safeTransfer(msg.sender, amount);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __TokenDebtTracker_init() internal onlyInitializing {\n __TokenDebtTracker_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __TokenDebtTracker_init_unchained() internal onlyInitializing {}\n\n /**\n * @dev Transfers tokens to the recipient if the contract has enough balance, or\n * records the debt if the transfer fails due to reasons unrelated to the contract's\n * balance (e.g. if the token forbids transfers to the recipient).\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n * @custom:error InsufficientBalance The contract doesn't have enough balance to transfer\n */\n function _transferOutOrTrackDebt(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) internal {\n uint256 balance = token.balanceOf(address(this));\n if (balance < amount) {\n revert InsufficientBalance(address(token), address(this), amount, balance);\n }\n _transferOutOrTrackDebtSkippingBalanceCheck(token, to, amount);\n }\n\n /**\n * @dev Transfers tokens to the recipient, or records the debt if the transfer fails\n * due to any reason, including insufficient balance.\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n */\n function _transferOutOrTrackDebtSkippingBalanceCheck(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) internal {\n // We can't use safeTransfer here because we can't try-catch internal calls\n bool success = _tryTransferOut(token, to, amount);\n if (!success) {\n tokenDebt[token][to] += amount;\n totalTokenDebt[token] += amount;\n emit TokenDebtAdded(address(token), to, amount);\n }\n }\n\n /**\n * @dev Either transfers tokens to the recepient or returns false. Supports tokens\n * thet revert or return false to indicate failure, and the non-compliant ones\n * that do not return any value.\n * @param token The token to transfer\n * @param to The recipient of the transfer\n * @param amount The amount to transfer\n * @return true if the transfer succeeded, false otherwise\n */\n function _tryTransferOut(\n IERC20Upgradeable token,\n address to,\n uint256 amount\n ) private returns (bool) {\n bytes memory callData = abi.encodeCall(token.transfer, (to, amount));\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(callData);\n return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\n }\n}\n" + }, + "contracts/lib/validators.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\nerror ZeroAddressNotAllowed();\n\n/// @notice Checks if the provided address is nonzero, reverts otherwise\n/// @param address_ Address to check\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\nfunction ensureNonzeroAddress(address address_) pure {\n if (address_ == address(0)) {\n revert ZeroAddressNotAllowed();\n }\n}\n" + }, + "contracts/MaxLoopsLimitHelper.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title MaxLoopsLimitHelper\n * @author Venus\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\n */\nabstract contract MaxLoopsLimitHelper {\n // Limit for the loops to avoid the DOS\n uint256 public maxLoopsLimit;\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 max loops limit is set\n event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\n\n /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\n error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function _setMaxLoopsLimit(uint256 limit) internal {\n require(limit > maxLoopsLimit, \"Comptroller: Invalid maxLoopsLimit\");\n\n uint256 oldMaxLoopsLimit = maxLoopsLimit;\n maxLoopsLimit = limit;\n\n emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\n }\n\n /**\n * @notice Compare the maxLoopsLimit with number of the times loop iterate\n * @param len Length of the loops iterate\n * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\n */\n function _ensureMaxLoops(uint256 len) internal view {\n if (len > maxLoopsLimit) {\n revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\n }\n }\n}\n" + }, + "contracts/Pool/PoolRegistry.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { PoolRegistryInterface } from \"./PoolRegistryInterface.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\n\n/**\n * @title PoolRegistry\n * @author Venus\n * @notice The Isolated Pools architecture centers around the `PoolRegistry` contract. The `PoolRegistry` maintains a directory of isolated lending\n * pools and can perform actions like creating and registering new pools, adding new markets to existing pools, setting and updating the pool's required\n * metadata, and providing the getter methods to get information on the pools.\n *\n * Isolated lending has three main components: PoolRegistry, pools, and markets. The PoolRegistry is responsible for managing pools.\n * It can create new pools, update pool metadata and manage markets within pools. PoolRegistry contains getter methods to get the details of\n * any existing pool like `getVTokenForAsset` and `getPoolsSupportedByAsset`. It also contains methods for updating pool metadata (`updatePoolMetadata`)\n * and setting pool name (`setPoolName`).\n *\n * The directory of pools is managed through two mappings: `_poolByComptroller` which is a hashmap with the comptroller address as the key and `VenusPool` as\n * the value and `_poolsByID` which is an array of comptroller addresses. Individual pools can be accessed by calling `getPoolByComptroller` with the pool's\n * comptroller address. `_poolsByID` is used to iterate through all of the pools.\n *\n * PoolRegistry also contains a map of asset addresses called `_supportedPools` that maps to an array of assets suppored by each pool. This array of pools by\n * asset is retrieved by calling `getPoolsSupportedByAsset`.\n *\n * PoolRegistry registers new isolated pools in the directory with the `createRegistryPool` method. Isolated pools are composed of independent markets with\n * specific assets and custom risk management configurations according to their markets.\n */\ncontract PoolRegistry is Ownable2StepUpgradeable, AccessControlledV8, PoolRegistryInterface {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n struct AddMarketInput {\n VToken vToken;\n uint256 collateralFactor;\n uint256 liquidationThreshold;\n uint256 initialSupply;\n address vTokenReceiver;\n uint256 supplyCap;\n uint256 borrowCap;\n }\n\n uint256 internal constant MAX_POOL_NAME_LENGTH = 100;\n\n /**\n * @notice Maps pool's comptroller address to metadata.\n */\n mapping(address => VenusPoolMetaData) public metadata;\n\n /**\n * @dev Maps pool ID to pool's comptroller address\n */\n mapping(uint256 => address) private _poolsByID;\n\n /**\n * @dev Total number of pools created.\n */\n uint256 private _numberOfPools;\n\n /**\n * @dev Maps comptroller address to Venus pool Index.\n */\n mapping(address => VenusPool) private _poolByComptroller;\n\n /**\n * @dev Maps pool's comptroller address to asset to vToken.\n */\n mapping(address => mapping(address => address)) private _vTokens;\n\n /**\n * @dev Maps asset to list of supported pools.\n */\n mapping(address => address[]) private _supportedPools;\n\n /**\n * @notice Emitted when a new Venus pool is added to the directory.\n */\n event PoolRegistered(address indexed comptroller, VenusPool pool);\n\n /**\n * @notice Emitted when a pool name is set.\n */\n event PoolNameSet(address indexed comptroller, string oldName, string newName);\n\n /**\n * @notice Emitted when a pool metadata is updated.\n */\n event PoolMetadataUpdated(\n address indexed comptroller,\n VenusPoolMetaData oldMetadata,\n VenusPoolMetaData newMetadata\n );\n\n /**\n * @notice Emitted when a Market is added to the pool.\n */\n event MarketAdded(address indexed comptroller, address indexed vTokenAddress);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner\n * @param accessControlManager_ AccessControlManager contract address\n */\n function initialize(address accessControlManager_) external initializer {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n }\n\n /**\n * @notice Adds a new Venus pool to the directory\n * @dev Price oracle must be configured before adding a pool\n * @param name The name of the pool\n * @param comptroller Pool's Comptroller contract\n * @param closeFactor The pool's close factor (scaled by 1e18)\n * @param liquidationIncentive The pool's liquidation incentive (scaled by 1e18)\n * @param minLiquidatableCollateral Minimal collateral for regular (non-batch) liquidations flow\n * @return index The index of the registered Venus pool\n * @custom:error ZeroAddressNotAllowed is thrown when Comptroller address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when price oracle address is zero\n */\n function addPool(\n string calldata name,\n Comptroller comptroller,\n uint256 closeFactor,\n uint256 liquidationIncentive,\n uint256 minLiquidatableCollateral\n ) external virtual returns (uint256 index) {\n _checkAccessAllowed(\"addPool(string,address,uint256,uint256,uint256)\");\n // Input validation\n ensureNonzeroAddress(address(comptroller));\n ensureNonzeroAddress(address(comptroller.oracle()));\n\n uint256 poolId = _registerPool(name, address(comptroller));\n\n // Set Venus pool parameters\n comptroller.setCloseFactor(closeFactor);\n comptroller.setLiquidationIncentive(liquidationIncentive);\n comptroller.setMinLiquidatableCollateral(minLiquidatableCollateral);\n\n return poolId;\n }\n\n /**\n * @notice Add a market to an existing pool and then mint to provide initial supply\n * @param input The structure describing the parameters for adding a market to a pool\n * @custom:error ZeroAddressNotAllowed is thrown when vToken address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when vTokenReceiver address is zero\n */\n function addMarket(AddMarketInput memory input) external {\n _checkAccessAllowed(\"addMarket(AddMarketInput)\");\n ensureNonzeroAddress(address(input.vToken));\n ensureNonzeroAddress(input.vTokenReceiver);\n require(input.initialSupply > 0, \"PoolRegistry: initialSupply is zero\");\n\n VToken vToken = input.vToken;\n address vTokenAddress = address(vToken);\n address comptrollerAddress = address(vToken.comptroller());\n Comptroller comptroller = Comptroller(comptrollerAddress);\n address underlyingAddress = vToken.underlying();\n IERC20Upgradeable underlying = IERC20Upgradeable(underlyingAddress);\n\n require(_poolByComptroller[comptrollerAddress].creator != address(0), \"PoolRegistry: Pool not registered\");\n // solhint-disable-next-line reason-string\n require(\n _vTokens[comptrollerAddress][underlyingAddress] == address(0),\n \"PoolRegistry: Market already added for asset comptroller combination\"\n );\n\n comptroller.supportMarket(vToken);\n comptroller.setCollateralFactor(vToken, input.collateralFactor, input.liquidationThreshold);\n\n uint256[] memory newSupplyCaps = new uint256[](1);\n uint256[] memory newBorrowCaps = new uint256[](1);\n VToken[] memory vTokens = new VToken[](1);\n\n newSupplyCaps[0] = input.supplyCap;\n newBorrowCaps[0] = input.borrowCap;\n vTokens[0] = vToken;\n\n comptroller.setMarketSupplyCaps(vTokens, newSupplyCaps);\n comptroller.setMarketBorrowCaps(vTokens, newBorrowCaps);\n\n _vTokens[comptrollerAddress][underlyingAddress] = vTokenAddress;\n _supportedPools[underlyingAddress].push(comptrollerAddress);\n\n uint256 amountToSupply = _transferIn(underlying, msg.sender, input.initialSupply);\n underlying.approve(vTokenAddress, 0);\n underlying.approve(vTokenAddress, amountToSupply);\n vToken.mintBehalf(input.vTokenReceiver, amountToSupply);\n\n emit MarketAdded(comptrollerAddress, vTokenAddress);\n }\n\n /**\n * @notice Modify existing Venus pool name\n * @param comptroller Pool's Comptroller\n * @param name New pool name\n */\n function setPoolName(address comptroller, string calldata name) external {\n _checkAccessAllowed(\"setPoolName(address,string)\");\n _ensureValidName(name);\n VenusPool storage pool = _poolByComptroller[comptroller];\n string memory oldName = pool.name;\n pool.name = name;\n emit PoolNameSet(comptroller, oldName, name);\n }\n\n /**\n * @notice Update metadata of an existing pool\n * @param comptroller Pool's Comptroller\n * @param metadata_ New pool metadata\n */\n function updatePoolMetadata(address comptroller, VenusPoolMetaData calldata metadata_) external {\n _checkAccessAllowed(\"updatePoolMetadata(address,VenusPoolMetaData)\");\n VenusPoolMetaData memory oldMetadata = metadata[comptroller];\n metadata[comptroller] = metadata_;\n emit PoolMetadataUpdated(comptroller, oldMetadata, metadata_);\n }\n\n /**\n * @notice Returns arrays of all Venus pools' data\n * @dev This function is not designed to be called in a transaction: it is too gas-intensive\n * @return A list of all pools within PoolRegistry, with details for each pool\n */\n function getAllPools() external view override returns (VenusPool[] memory) {\n uint256 numberOfPools_ = _numberOfPools; // storage load to save gas\n VenusPool[] memory _pools = new VenusPool[](numberOfPools_);\n for (uint256 i = 1; i <= numberOfPools_; ++i) {\n address comptroller = _poolsByID[i];\n _pools[i - 1] = (_poolByComptroller[comptroller]);\n }\n return _pools;\n }\n\n /**\n * @param comptroller The comptroller proxy address associated to the pool\n * @return Returns Venus pool\n */\n function getPoolByComptroller(address comptroller) external view override returns (VenusPool memory) {\n return _poolByComptroller[comptroller];\n }\n\n /**\n * @param comptroller comptroller of Venus pool\n * @return Returns Metadata of Venus pool\n */\n function getVenusPoolMetadata(address comptroller) external view override returns (VenusPoolMetaData memory) {\n return metadata[comptroller];\n }\n\n function getVTokenForAsset(address comptroller, address asset) external view override returns (address) {\n return _vTokens[comptroller][asset];\n }\n\n function getPoolsSupportedByAsset(address asset) external view override returns (address[] memory) {\n return _supportedPools[asset];\n }\n\n /**\n * @dev Adds a new Venus pool to the directory (without checking msg.sender).\n * @param name The name of the pool\n * @param comptroller The pool's Comptroller proxy contract address\n * @return The index of the registered Venus pool\n */\n function _registerPool(string calldata name, address comptroller) internal returns (uint256) {\n VenusPool storage storedPool = _poolByComptroller[comptroller];\n\n require(storedPool.creator == address(0), \"PoolRegistry: Pool already exists in the directory.\");\n _ensureValidName(name);\n\n ++_numberOfPools;\n uint256 numberOfPools_ = _numberOfPools; // cache on stack to save storage read gas\n\n VenusPool memory pool = VenusPool(name, msg.sender, comptroller, block.number, block.timestamp);\n\n _poolsByID[numberOfPools_] = comptroller;\n _poolByComptroller[comptroller] = pool;\n\n emit PoolRegistered(comptroller, pool);\n return numberOfPools_;\n }\n\n function _transferIn(\n IERC20Upgradeable token,\n address from,\n uint256 amount\n ) internal returns (uint256) {\n uint256 balanceBefore = token.balanceOf(address(this));\n token.safeTransferFrom(from, address(this), amount);\n uint256 balanceAfter = token.balanceOf(address(this));\n return balanceAfter - balanceBefore;\n }\n\n function _ensureValidName(string calldata name) internal pure {\n require(bytes(name).length <= MAX_POOL_NAME_LENGTH, \"Pool's name is too large\");\n }\n}\n" + }, + "contracts/Pool/PoolRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title PoolRegistryInterface\n * @author Venus\n * @notice Interface implemented by `PoolRegistry`.\n */\ninterface PoolRegistryInterface {\n /**\n * @notice Struct for a Venus interest rate pool.\n */\n struct VenusPool {\n string name;\n address creator;\n address comptroller;\n uint256 blockPosted;\n uint256 timestampPosted;\n }\n\n /**\n * @notice Struct for a Venus interest rate pool metadata.\n */\n struct VenusPoolMetaData {\n string category;\n string logoURL;\n string description;\n }\n\n /// @notice Get all pools in PoolRegistry\n function getAllPools() external view returns (VenusPool[] memory);\n\n /// @notice Get a pool by comptroller address\n function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\n\n /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\n function getVTokenForAsset(address comptroller, address asset) external view returns (address);\n\n /// @notice Get the addresss of the Pools supported that include a market for the provided asset\n function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\n\n /// @notice Get the metadata of a Pool by comptroller address\n function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\n}\n" + }, + "contracts/Rewards/RewardsDistributor.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { MaxLoopsLimitHelper } from \"../MaxLoopsLimitHelper.sol\";\n\n/**\n * @title `RewardsDistributor`\n * @author Venus\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\n * token to be released each block for borrowers and suppliers, which is distributed based on a user’s percentage of the borrows or supplies\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per block.\n *\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\n */\ncontract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, AccessControlledV8, MaxLoopsLimitHelper {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n struct RewardToken {\n // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\n uint224 index;\n // The block number the index was last updated at\n uint32 block;\n // The block number at which to stop rewards\n uint32 lastRewardingBlock;\n }\n\n /// @notice The initial REWARD TOKEN index for a market\n uint224 public constant INITIAL_INDEX = 1e36;\n\n /// @notice The REWARD TOKEN market supply state for each market\n mapping(address => RewardToken) public rewardTokenSupplyState;\n\n /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\n mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\n\n /// @notice The REWARD TOKEN accrued but not yet transferred to each user\n mapping(address => uint256) public rewardTokenAccrued;\n\n /// @notice The rate at which rewardToken is distributed to the corresponding borrow market (per block)\n mapping(address => uint256) public rewardTokenBorrowSpeeds;\n\n /// @notice The rate at which rewardToken is distributed to the corresponding supply market (per block)\n mapping(address => uint256) public rewardTokenSupplySpeeds;\n\n /// @notice The REWARD TOKEN market borrow state for each market\n mapping(address => RewardToken) public rewardTokenBorrowState;\n\n /// @notice The portion of REWARD TOKEN that each contributor receives per block\n mapping(address => uint256) public rewardTokenContributorSpeeds;\n\n /// @notice Last block at which a contributor's REWARD TOKEN rewards have been allocated\n mapping(address => uint256) public lastContributorBlock;\n\n /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\n mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\n\n Comptroller private comptroller;\n\n IERC20Upgradeable public rewardToken;\n\n /// @notice Emitted when REWARD TOKEN is distributed to a supplier\n event DistributedSupplierRewardToken(\n VToken indexed vToken,\n address indexed supplier,\n uint256 rewardTokenDelta,\n uint256 rewardTokenTotal,\n uint256 rewardTokenSupplyIndex\n );\n\n /// @notice Emitted when REWARD TOKEN is distributed to a borrower\n event DistributedBorrowerRewardToken(\n VToken indexed vToken,\n address indexed borrower,\n uint256 rewardTokenDelta,\n uint256 rewardTokenTotal,\n uint256 rewardTokenBorrowIndex\n );\n\n /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\n event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\n event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /// @notice Emitted when REWARD TOKEN is granted by admin\n event RewardTokenGranted(address indexed recipient, uint256 amount);\n\n /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\n event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\n\n /// @notice Emitted when a market is initialized\n event MarketInitialized(address indexed vToken);\n\n /// @notice Emitted when a reward token supply index is updated\n event RewardTokenSupplyIndexUpdated(address indexed vToken);\n\n /// @notice Emitted when a reward token borrow index is updated\n event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\n\n /// @notice Emitted when a reward for contributor is updated\n event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\n\n /// @notice Emitted when a reward token last rewarding block for supply is updated\n event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\n\n /// @notice Emitted when a reward token last rewarding block for borrow is updated\n event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\n\n modifier onlyComptroller() {\n require(address(comptroller) == msg.sender, \"Only comptroller can call this function\");\n _;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice RewardsDistributor initializer\n * @dev Initializes the deployer to owner\n * @param comptroller_ Comptroller to attach the reward distributor to\n * @param rewardToken_ Reward token to distribute\n * @param loopsLimit_ Maximum number of iterations for the loops in this contract\n * @param accessControlManager_ AccessControlManager contract address\n */\n function initialize(\n Comptroller comptroller_,\n IERC20Upgradeable rewardToken_,\n uint256 loopsLimit_,\n address accessControlManager_\n ) external initializer {\n comptroller = comptroller_;\n rewardToken = rewardToken_;\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n\n _setMaxLoopsLimit(loopsLimit_);\n }\n\n function initializeMarket(address vToken) external onlyComptroller {\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n RewardToken storage borrowState = rewardTokenBorrowState[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 = INITIAL_INDEX;\n }\n\n if (borrowState.index == 0) {\n // Initialize borrow state index with default value\n borrowState.index = INITIAL_INDEX;\n }\n\n /*\n * Update market state block numbers\n */\n supplyState.block = borrowState.block = blockNumber;\n\n emit MarketInitialized(vToken);\n }\n\n /*** Reward Token Distribution ***/\n\n /**\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\n * Borrowers will begin to accrue after the first interaction with the protocol.\n * @dev This function should only be called when the user has a borrow position in the market\n * (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\n * We avoid an external call to check if they are in the market to save gas because this function is called in many places\n * @param vToken The market in which the borrower is interacting\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\n * @param marketBorrowIndex The current global borrow index of vToken\n */\n function distributeBorrowerRewardToken(\n address vToken,\n address borrower,\n Exp memory marketBorrowIndex\n ) external onlyComptroller {\n _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\n }\n\n function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\n _updateRewardTokenSupplyIndex(vToken);\n }\n\n /**\n * @notice Transfer REWARD TOKEN to the recipient\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\n * @param recipient The address of the recipient to transfer REWARD TOKEN to\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\n */\n function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\n uint256 amountLeft = _grantRewardToken(recipient, amount);\n require(amountLeft == 0, \"insufficient rewardToken for grant\");\n emit RewardTokenGranted(recipient, amount);\n }\n\n function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\n _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\n }\n\n /**\n * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\n * @param vTokens The markets whose REWARD TOKEN speed to update\n * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\n * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\n */\n function setRewardTokenSpeeds(\n VToken[] memory vTokens,\n uint256[] memory supplySpeeds,\n uint256[] memory borrowSpeeds\n ) external {\n _checkAccessAllowed(\"setRewardTokenSpeeds(address[],uint256[],uint256[])\");\n uint256 numTokens = vTokens.length;\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \"invalid setRewardTokenSpeeds\");\n\n for (uint256 i; i < numTokens; ++i) {\n _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\n }\n }\n\n /**\n * @notice Set REWARD TOKEN last rewarding block for the specified markets\n * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\n * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\n * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\n */\n function setLastRewardingBlocks(\n VToken[] calldata vTokens,\n uint32[] calldata supplyLastRewardingBlocks,\n uint32[] calldata borrowLastRewardingBlocks\n ) external {\n _checkAccessAllowed(\"setLastRewardingBlock(address[],uint32[],uint32[])\");\n uint256 numTokens = vTokens.length;\n require(\n numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\n \"RewardsDistributor::setLastRewardingBlocks invalid input\"\n );\n\n for (uint256 i; i < numTokens; ) {\n _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Set REWARD TOKEN speed for a single contributor\n * @param contributor The contributor whose REWARD TOKEN speed to update\n * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\n */\n function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\n // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\n updateContributorRewards(contributor);\n if (rewardTokenSpeed == 0) {\n // release storage\n delete lastContributorBlock[contributor];\n } else {\n lastContributorBlock[contributor] = getBlockNumber();\n }\n rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\n\n emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\n }\n\n function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\n _distributeSupplierRewardToken(vToken, supplier);\n }\n\n /**\n * @notice Claim all the rewardToken accrued by holder in all markets\n * @param holder The address to claim REWARD TOKEN for\n */\n function claimRewardToken(address holder) external {\n return claimRewardToken(holder, comptroller.getAllMarkets());\n }\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\n * @param contributor The address to calculate contributor rewards for\n */\n function updateContributorRewards(address contributor) public {\n uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\n uint256 blockNumber = getBlockNumber();\n uint256 deltaBlocks = sub_(blockNumber, lastContributorBlock[contributor]);\n if (deltaBlocks > 0 && rewardTokenSpeed > 0) {\n uint256 newAccrued = mul_(deltaBlocks, rewardTokenSpeed);\n uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\n\n rewardTokenAccrued[contributor] = contributorAccrued;\n lastContributorBlock[contributor] = blockNumber;\n\n emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\n }\n }\n\n /**\n * @notice Claim all the rewardToken accrued by holder in the specified markets\n * @param holder The address to claim REWARD TOKEN for\n * @param vTokens The list of markets to claim REWARD TOKEN in\n */\n function claimRewardToken(address holder, VToken[] memory vTokens) public {\n uint256 vTokensCount = vTokens.length;\n\n _ensureMaxLoops(vTokensCount);\n\n for (uint256 i; i < vTokensCount; ++i) {\n VToken vToken = vTokens[i];\n require(comptroller.isMarketListed(vToken), \"market must be listed\");\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\n _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\n _updateRewardTokenSupplyIndex(address(vToken));\n _distributeSupplierRewardToken(address(vToken), holder);\n }\n rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\n }\n\n function getBlockNumber() public view virtual returns (uint256) {\n return block.number;\n }\n\n /**\n * @notice Set REWARD TOKEN last rewarding block for a single market.\n * @param vToken market's whose reward token last rewarding block to be updated\n * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\n * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\n */\n function _setLastRewardingBlock(\n VToken vToken,\n uint32 supplyLastRewardingBlock,\n uint32 borrowLastRewardingBlock\n ) internal {\n require(comptroller.isMarketListed(vToken), \"rewardToken market is not listed\");\n\n uint256 blockNumber = getBlockNumber();\n\n require(supplyLastRewardingBlock > blockNumber, \"setting last rewarding block in the past is not allowed\");\n require(borrowLastRewardingBlock > blockNumber, \"setting last rewarding block in the past is not allowed\");\n\n uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\n uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\n\n require(\n currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\n \"this RewardsDistributor is already locked\"\n );\n require(\n currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\n \"this RewardsDistributor is already locked\"\n );\n\n if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\n rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\n emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\n }\n\n if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\n rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\n emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\n }\n }\n\n /**\n * @notice Set REWARD TOKEN speed for a single market.\n * @param vToken market's whose reward token rate to be updated\n * @param supplySpeed New supply-side REWARD TOKEN speed for market\n * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\n */\n function _setRewardTokenSpeed(\n VToken vToken,\n uint256 supplySpeed,\n uint256 borrowSpeed\n ) internal {\n require(comptroller.isMarketListed(vToken), \"rewardToken market is not listed\");\n\n if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\n // Supply speed updated so let's update supply state to ensure that\n // 1. REWARD TOKEN accrued properly for the old speed, and\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\n _updateRewardTokenSupplyIndex(address(vToken));\n\n // Update speed and emit event\n rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\n emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\n }\n\n if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\n // Borrow speed updated so let's update borrow state to ensure that\n // 1. REWARD TOKEN accrued properly for the old speed, and\n // 2. REWARD TOKEN accrued at the new speed starts after this block.\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\n\n // Update speed and emit event\n rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\n emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\n }\n }\n\n /**\n * @notice Calculate REWARD TOKEN 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 REWARD TOKEN to\n */\n function _distributeSupplierRewardToken(address vToken, address supplier) internal {\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n uint256 supplyIndex = supplyState.index;\n uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\n\n // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\n rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\n\n if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\n // Covers the case where users supplied tokens before the market's supply state index was set.\n // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\n // set for the market.\n supplierIndex = INITIAL_INDEX;\n }\n\n // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\n\n uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\n\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\n uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\n\n uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\n rewardTokenAccrued[supplier] = supplierAccrued;\n\n emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\n }\n\n /**\n * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\n * @param vToken The market in which the borrower is interacting\n * @param borrower The address of the borrower to distribute REWARD TOKEN to\n * @param marketBorrowIndex The current global borrow index of vToken\n */\n function _distributeBorrowerRewardToken(\n address vToken,\n address borrower,\n Exp memory marketBorrowIndex\n ) internal {\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\n uint256 borrowIndex = borrowState.index;\n uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\n\n // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\n rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\n\n if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\n // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\n // set for the market.\n borrowerIndex = INITIAL_INDEX;\n }\n\n // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\n\n uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\n\n // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\n if (borrowerAmount != 0) {\n uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\n\n uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\n rewardTokenAccrued[borrower] = borrowerAccrued;\n\n emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\n }\n }\n\n /**\n * @notice Transfer REWARD TOKEN to the user.\n * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\n * @param user The address of the user to transfer REWARD TOKEN to\n * @param amount The amount of REWARD TOKEN to (possibly) transfer\n * @return The amount of REWARD TOKEN which was NOT transferred to the user\n */\n function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\n uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\n if (amount > 0 && amount <= rewardTokenRemaining) {\n rewardToken.safeTransfer(user, amount);\n return 0;\n }\n return amount;\n }\n\n /**\n * @notice Accrue REWARD TOKEN to the market by updating the supply index\n * @param vToken The market whose supply index to update\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\n */\n function _updateRewardTokenSupplyIndex(address vToken) internal {\n RewardToken storage supplyState = rewardTokenSupplyState[vToken];\n uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {\n blockNumber = supplyState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));\n\n if (deltaBlocks > 0 && supplySpeed > 0) {\n uint256 supplyTokens = VToken(vToken).totalSupply();\n uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens > 0\n ? fraction(accruedSinceUpdate, supplyTokens)\n : Double({ mantissa: 0 });\n supplyState.index = safe224(\n add_(Double({ mantissa: supplyState.index }), ratio).mantissa,\n \"new index exceeds 224 bits\"\n );\n supplyState.block = blockNumber;\n } else if (deltaBlocks > 0) {\n supplyState.block = blockNumber;\n }\n\n emit RewardTokenSupplyIndexUpdated(vToken);\n }\n\n /**\n * @notice Accrue REWARD TOKEN to the market by updating the borrow index\n * @param vToken The market whose borrow index to update\n * @param marketBorrowIndex The current global borrow index of vToken\n * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\n */\n function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\n RewardToken storage borrowState = rewardTokenBorrowState[vToken];\n uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\n uint32 blockNumber = safe32(getBlockNumber(), \"block number exceeds 32 bits\");\n\n if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {\n blockNumber = borrowState.lastRewardingBlock;\n }\n\n uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));\n if (deltaBlocks > 0 && borrowSpeed > 0) {\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint256 accruedSinceUpdate = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount > 0\n ? fraction(accruedSinceUpdate, borrowAmount)\n : Double({ mantissa: 0 });\n borrowState.index = safe224(\n add_(Double({ mantissa: borrowState.index }), ratio).mantissa,\n \"new index exceeds 224 bits\"\n );\n borrowState.block = blockNumber;\n } else if (deltaBlocks > 0) {\n borrowState.block = blockNumber;\n }\n\n emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\n }\n}\n" + }, + "contracts/RiskFund/IProtocolShareReserve.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title IProtocolShareReserve\n * @author Venus\n * @notice Interface implemented by `ProtocolShareReserve`.\n */\ninterface IProtocolShareReserve {\n function updateAssetsState(address comptroller, address asset) external;\n}\n" + }, + "contracts/RiskFund/IRiskFund.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\n/**\n * @title IRiskFund\n * @author Venus\n * @notice Interface implemented by `RiskFund`.\n */\ninterface IRiskFund {\n function swapPoolsAssets(\n address[] calldata markets,\n uint256[] calldata amountsOutMin,\n address[][] calldata paths,\n uint256 deadline\n ) external returns (uint256);\n\n function transferReserveForAuction(address comptroller, uint256 amount) external returns (uint256);\n\n function updateAssetsState(address comptroller, address asset) external;\n\n function convertibleBaseAsset() external view returns (address);\n\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256);\n}\n" + }, + "contracts/RiskFund/ProtocolShareReserve.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\nimport { IProtocolShareReserve } from \"./IProtocolShareReserve.sol\";\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { ReserveHelpers } from \"./ReserveHelpers.sol\";\nimport { IRiskFund } from \"./IRiskFund.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\n\ncontract ProtocolShareReserve is ExponentialNoError, ReserveHelpers, IProtocolShareReserve {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n address public protocolIncome;\n address public riskFund;\n // Percentage of funds not sent to the RiskFund contract when the funds are released, following the project Tokenomics\n uint256 private constant PROTOCOL_SHARE_PERCENTAGE = 50;\n uint256 private constant BASE_UNIT = 100;\n\n /// @notice Emitted when funds are released\n event FundsReleased(address indexed comptroller, address indexed asset, uint256 amount);\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner.\n * @param protocolIncome_ The address protocol income will be sent to\n * @param riskFund_ Risk fund address\n * @custom:error ZeroAddressNotAllowed is thrown when protocol income address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\n */\n function initialize(address protocolIncome_, address riskFund_) external initializer {\n ensureNonzeroAddress(protocolIncome_);\n ensureNonzeroAddress(riskFund_);\n\n __Ownable2Step_init();\n\n protocolIncome = protocolIncome_;\n riskFund = riskFund_;\n }\n\n /**\n * @notice Pool registry setter.\n * @param poolRegistry_ Address of the pool registry\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Release funds\n * @param comptroller Pool's Comptroller\n * @param asset Asset to be released\n * @param amount Amount to release\n * @return Number of total released tokens\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function releaseFunds(\n address comptroller,\n address asset,\n uint256 amount\n ) external nonReentrant returns (uint256) {\n ensureNonzeroAddress(asset);\n require(amount <= _poolsAssetsReserves[comptroller][asset], \"ProtocolShareReserve: Insufficient pool balance\");\n\n assetsReserves[asset] -= amount;\n _poolsAssetsReserves[comptroller][asset] -= amount;\n uint256 protocolIncomeAmount = mul_(\n Exp({ mantissa: amount }),\n div_(Exp({ mantissa: PROTOCOL_SHARE_PERCENTAGE * EXP_SCALE }), BASE_UNIT)\n ).mantissa;\n\n address riskFund_ = riskFund;\n\n emit FundsReleased(comptroller, asset, amount);\n\n IERC20Upgradeable(asset).safeTransfer(protocolIncome, protocolIncomeAmount);\n IERC20Upgradeable(asset).safeTransfer(riskFund_, amount - protocolIncomeAmount);\n\n // Update the pool asset's state in the risk fund for the above transfer.\n IRiskFund(riskFund_).updateAssetsState(comptroller, asset);\n\n return amount;\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to the protocol share reserve.\n * @param comptroller Comptroller address(pool)\n * @param asset Asset address.\n */\n function updateAssetsState(address comptroller, address asset)\n public\n override(IProtocolShareReserve, ReserveHelpers)\n {\n super.updateAssetsState(comptroller, asset);\n }\n}\n" + }, + "contracts/RiskFund/ReserveHelpers.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\n\ncontract ReserveHelpers is Ownable2StepUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n uint256 private constant NOT_ENTERED = 1;\n\n uint256 private constant ENTERED = 2;\n\n // Store the previous state for the asset transferred to ProtocolShareReserve combined(for all pools).\n mapping(address => uint256) public assetsReserves;\n\n // Store the asset's reserve per pool in the ProtocolShareReserve.\n // Comptroller(pool) -> Asset -> amount\n mapping(address => mapping(address => uint256)) internal _poolsAssetsReserves;\n\n // Address of pool registry contract\n address public poolRegistry;\n\n /**\n * @dev Guard variable for re-entrancy checks\n */\n uint256 internal status;\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 */\n uint256[46] private __gap;\n\n /// @notice Event emitted after the update of the assets reserves.\n /// @param comptroller Pool's Comptroller address\n /// @param asset Token address\n /// @param amount An amount by which the reserves have increased\n event AssetsReservesUpdated(address indexed comptroller, address indexed asset, uint256 amount);\n\n /// @notice event emitted on sweep token success\n event SweepToken(address indexed token, address indexed to, uint256 amount);\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(status != ENTERED, \"re-entered\");\n status = ENTERED;\n _;\n status = NOT_ENTERED;\n }\n\n /**\n * @notice A public function to sweep accidental BEP-20 transfers to this contract. Tokens are sent to the address `to`, provided in input\n * @param _token The address of the BEP-20 token to sweep\n * @param _to Recipient of the output tokens.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n * @custom:access Only Owner\n */\n function sweepToken(address _token, address _to) external onlyOwner nonReentrant {\n ensureNonzeroAddress(_to);\n uint256 balanceDfference_;\n uint256 balance_ = IERC20Upgradeable(_token).balanceOf(address(this));\n\n require(balance_ > assetsReserves[_token], \"ReserveHelpers: Zero surplus tokens\");\n unchecked {\n balanceDfference_ = balance_ - assetsReserves[_token];\n }\n\n emit SweepToken(_token, _to, balanceDfference_);\n IERC20Upgradeable(_token).safeTransfer(_to, balanceDfference_);\n }\n\n /**\n * @notice Get the Amount of the asset in the risk fund for the specific pool.\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n * @return Asset's reserve in risk fund.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function getPoolAssetReserve(address comptroller, address asset) external view returns (uint256) {\n ensureNonzeroAddress(asset);\n require(ComptrollerInterface(comptroller).isComptroller(), \"ReserveHelpers: Comptroller address invalid\");\n return _poolsAssetsReserves[comptroller][asset];\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund\n * and transferring funds to the protocol share reserve\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n * @custom:error ZeroAddressNotAllowed is thrown when asset address is zero\n */\n function updateAssetsState(address comptroller, address asset) public virtual {\n ensureNonzeroAddress(asset);\n require(ComptrollerInterface(comptroller).isComptroller(), \"ReserveHelpers: Comptroller address invalid\");\n address poolRegistry_ = poolRegistry;\n require(poolRegistry_ != address(0), \"ReserveHelpers: Pool Registry address is not set\");\n require(\n PoolRegistryInterface(poolRegistry_).getVTokenForAsset(comptroller, asset) != address(0),\n \"ReserveHelpers: The pool doesn't support the asset\"\n );\n\n uint256 currentBalance = IERC20Upgradeable(asset).balanceOf(address(this));\n uint256 assetReserve = assetsReserves[asset];\n if (currentBalance > assetReserve) {\n uint256 balanceDifference;\n unchecked {\n balanceDifference = currentBalance - assetReserve;\n }\n assetsReserves[asset] += balanceDifference;\n _poolsAssetsReserves[comptroller][asset] += balanceDifference;\n emit AssetsReservesUpdated(comptroller, asset, balanceDifference);\n }\n }\n}\n" + }, + "contracts/RiskFund/RiskFund.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { IRiskFund } from \"./IRiskFund.sol\";\nimport { ReserveHelpers } from \"./ReserveHelpers.sol\";\nimport { ExponentialNoError } from \"../ExponentialNoError.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { IPancakeswapV2Router } from \"../IPancakeswapV2Router.sol\";\nimport { MaxLoopsLimitHelper } from \"../MaxLoopsLimitHelper.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\nimport { ApproveOrRevert } from \"../lib/ApproveOrRevert.sol\";\n\n/**\n * @title RiskFund\n * @author Venus\n * @notice Contract with basic features to track/hold different assets for different Comptrollers.\n * @dev This contract does not support BNB.\n */\ncontract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, MaxLoopsLimitHelper, IRiskFund {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using ApproveOrRevert for IERC20Upgradeable;\n\n address public convertibleBaseAsset;\n address public shortfall;\n address public pancakeSwapRouter;\n uint256 public minAmountToConvert;\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @notice Emitted when shortfall contract address is updated\n event ShortfallContractUpdated(address indexed oldShortfallContract, address indexed newShortfallContract);\n\n /// @notice Emitted when convertible base asset is updated\n event ConvertibleBaseAssetUpdated(address indexed oldConvertibleBaseAsset, address indexed newConvertibleBaseAsset);\n\n /// @notice Emitted when PancakeSwap router contract address is updated\n event PancakeSwapRouterUpdated(address indexed oldPancakeSwapRouter, address indexed newPancakeSwapRouter);\n\n /// @notice Emitted when minimum amount to convert is updated\n event MinAmountToConvertUpdated(uint256 oldMinAmountToConvert, uint256 newMinAmountToConvert);\n\n /// @notice Emitted when pools assets are swapped\n event SwappedPoolsAssets(address[] markets, uint256[] amountsOutMin, uint256 totalAmount);\n\n /// @notice Emitted when reserves are transferred for auction\n event TransferredReserveForAuction(address indexed comptroller, uint256 amount);\n\n /// @dev Note that the contract is upgradeable. Use initialize() or reinitializers\n /// to set the state variables.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the deployer to owner.\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\n * @param minAmountToConvert_ Minimum amount assets must be worth to convert into base asset\n * @param convertibleBaseAsset_ Address of the base asset\n * @param accessControlManager_ Address of the access control contract\n * @param loopsLimit_ Limit for the loops in the contract to avoid DOS\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\n */\n function initialize(\n address pancakeSwapRouter_,\n uint256 minAmountToConvert_,\n address convertibleBaseAsset_,\n address accessControlManager_,\n uint256 loopsLimit_\n ) external initializer {\n ensureNonzeroAddress(pancakeSwapRouter_);\n ensureNonzeroAddress(convertibleBaseAsset_);\n require(minAmountToConvert_ > 0, \"Risk Fund: Invalid min amount to convert\");\n require(loopsLimit_ > 0, \"Risk Fund: Loops limit can not be zero\");\n\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n\n pancakeSwapRouter = pancakeSwapRouter_;\n minAmountToConvert = minAmountToConvert_;\n convertibleBaseAsset = convertibleBaseAsset_;\n\n _setMaxLoopsLimit(loopsLimit_);\n }\n\n /**\n * @notice Pool registry setter\n * @param poolRegistry_ Address of the pool registry\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function setPoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Shortfall contract address setter\n * @param shortfallContractAddress_ Address of the auction contract\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n */\n function setShortfallContractAddress(address shortfallContractAddress_) external onlyOwner {\n ensureNonzeroAddress(shortfallContractAddress_);\n\n address oldShortfallContractAddress = shortfall;\n shortfall = shortfallContractAddress_;\n emit ShortfallContractUpdated(oldShortfallContractAddress, shortfallContractAddress_);\n }\n\n /**\n * @notice PancakeSwap router address setter\n * @param pancakeSwapRouter_ Address of the PancakeSwap router\n * @custom:error ZeroAddressNotAllowed is thrown when PCS router address is zero\n */\n function setPancakeSwapRouter(address pancakeSwapRouter_) external onlyOwner {\n ensureNonzeroAddress(pancakeSwapRouter_);\n address oldPancakeSwapRouter = pancakeSwapRouter;\n pancakeSwapRouter = pancakeSwapRouter_;\n emit PancakeSwapRouterUpdated(oldPancakeSwapRouter, pancakeSwapRouter_);\n }\n\n /**\n * @notice Min amount to convert setter\n * @param minAmountToConvert_ Min amount to convert.\n */\n function setMinAmountToConvert(uint256 minAmountToConvert_) external {\n _checkAccessAllowed(\"setMinAmountToConvert(uint256)\");\n require(minAmountToConvert_ > 0, \"Risk Fund: Invalid min amount to convert\");\n uint256 oldMinAmountToConvert = minAmountToConvert;\n minAmountToConvert = minAmountToConvert_;\n emit MinAmountToConvertUpdated(oldMinAmountToConvert, minAmountToConvert_);\n }\n\n /**\n * @notice Sets a new convertible base asset\n * @param _convertibleBaseAsset Address for new convertible base asset.\n */\n function setConvertibleBaseAsset(address _convertibleBaseAsset) external {\n _checkAccessAllowed(\"setConvertibleBaseAsset(address)\");\n require(_convertibleBaseAsset != address(0), \"Risk Fund: new convertible base asset address invalid\");\n\n address oldConvertibleBaseAsset = convertibleBaseAsset;\n convertibleBaseAsset = _convertibleBaseAsset;\n\n emit ConvertibleBaseAssetUpdated(oldConvertibleBaseAsset, _convertibleBaseAsset);\n }\n\n /**\n * @notice Swap array of pool assets into base asset's tokens of at least a minimum amount\n * @param markets Array of vTokens whose assets to swap for base asset\n * @param amountsOutMin Minimum amount to receive for swap\n * @param paths A path consisting of PCS token pairs for each swap\n * @param deadline Deadline for the swap\n * @return Number of swapped tokens\n * @custom:error ZeroAddressNotAllowed is thrown if PoolRegistry contract address is not configured\n */\n function swapPoolsAssets(\n address[] calldata markets,\n uint256[] calldata amountsOutMin,\n address[][] calldata paths,\n uint256 deadline\n ) external override nonReentrant returns (uint256) {\n _checkAccessAllowed(\"swapPoolsAssets(address[],uint256[],address[][],uint256)\");\n require(deadline >= block.timestamp, \"Risk fund: deadline passed\");\n address poolRegistry_ = poolRegistry;\n ensureNonzeroAddress(poolRegistry_);\n require(markets.length == amountsOutMin.length, \"Risk fund: markets and amountsOutMin are unequal lengths\");\n require(markets.length == paths.length, \"Risk fund: markets and paths are unequal lengths\");\n\n uint256 totalAmount;\n uint256 marketsCount = markets.length;\n\n _ensureMaxLoops(marketsCount);\n\n for (uint256 i; i < marketsCount; ++i) {\n address comptroller = address(VToken(markets[i]).comptroller());\n\n PoolRegistry.VenusPool memory pool = PoolRegistry(poolRegistry_).getPoolByComptroller(comptroller);\n require(pool.comptroller == comptroller, \"comptroller doesn't exist pool registry\");\n require(Comptroller(comptroller).isMarketListed(VToken(markets[i])), \"market is not listed\");\n\n uint256 swappedTokens = _swapAsset(VToken(markets[i]), comptroller, amountsOutMin[i], paths[i]);\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] += swappedTokens;\n assetsReserves[convertibleBaseAsset] += swappedTokens;\n totalAmount = totalAmount + swappedTokens;\n }\n\n emit SwappedPoolsAssets(markets, amountsOutMin, totalAmount);\n\n return totalAmount;\n }\n\n /**\n * @notice Transfer tokens for auction.\n * @param comptroller Comptroller of the pool.\n * @param amount Amount to be transferred to auction contract.\n * @return Number reserved tokens.\n */\n function transferReserveForAuction(address comptroller, uint256 amount)\n external\n override\n nonReentrant\n returns (uint256)\n {\n address shortfall_ = shortfall;\n require(msg.sender == shortfall_, \"Risk fund: Only callable by Shortfall contract\");\n require(\n amount <= _poolsAssetsReserves[comptroller][convertibleBaseAsset],\n \"Risk Fund: Insufficient pool reserve.\"\n );\n unchecked {\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] =\n _poolsAssetsReserves[comptroller][convertibleBaseAsset] -\n amount;\n }\n unchecked {\n assetsReserves[convertibleBaseAsset] = assetsReserves[convertibleBaseAsset] - amount;\n }\n\n emit TransferredReserveForAuction(comptroller, amount);\n IERC20Upgradeable(convertibleBaseAsset).safeTransfer(shortfall_, amount);\n\n return amount;\n }\n\n /**\n * @notice Set the limit for the loops can iterate to avoid the DOS\n * @param limit Limit for the max loops can execute at a time\n */\n function setMaxLoopsLimit(uint256 limit) external onlyOwner {\n _setMaxLoopsLimit(limit);\n }\n\n /**\n * @notice Get the Amount of the Base asset in the risk fund for the specific pool.\n * @param comptroller Comptroller address(pool).\n * @return Base Asset's reserve in risk fund.\n */\n function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256) {\n require(ComptrollerInterface(comptroller).isComptroller(), \"Risk Fund: Comptroller address invalid\");\n return _poolsAssetsReserves[comptroller][convertibleBaseAsset];\n }\n\n /**\n * @notice Update the reserve of the asset for the specific pool after transferring to risk fund.\n * @param comptroller Comptroller address(pool).\n * @param asset Asset address.\n */\n function updateAssetsState(address comptroller, address asset) public override(IRiskFund, ReserveHelpers) {\n super.updateAssetsState(comptroller, asset);\n }\n\n /**\n * @dev Swap single asset to base asset.\n * @param vToken VToken\n * @param comptroller Comptroller address\n * @param amountOutMin Minimum amount to receive for swap\n * @param path A path for the swap consisting of PCS token pairs\n * @return Number of swapped tokens.\n */\n function _swapAsset(\n VToken vToken,\n address comptroller,\n uint256 amountOutMin,\n address[] calldata path\n ) internal returns (uint256) {\n require(amountOutMin != 0, \"RiskFund: amountOutMin must be greater than 0 to swap vToken\");\n uint256 totalAmount;\n\n address underlyingAsset = vToken.underlying();\n address convertibleBaseAsset_ = convertibleBaseAsset;\n uint256 balanceOfUnderlyingAsset = _poolsAssetsReserves[comptroller][underlyingAsset];\n\n if (balanceOfUnderlyingAsset == 0) {\n return 0;\n }\n\n ResilientOracleInterface oracle = ComptrollerViewInterface(comptroller).oracle();\n oracle.updateAssetPrice(convertibleBaseAsset_);\n Exp memory baseAssetPrice = Exp({ mantissa: oracle.getPrice(convertibleBaseAsset_) });\n uint256 amountOutMinInUsd = mul_ScalarTruncate(baseAssetPrice, amountOutMin);\n\n require(amountOutMinInUsd >= minAmountToConvert, \"RiskFund: minAmountToConvert violated\");\n\n assetsReserves[underlyingAsset] -= balanceOfUnderlyingAsset;\n _poolsAssetsReserves[comptroller][underlyingAsset] -= balanceOfUnderlyingAsset;\n\n if (underlyingAsset != convertibleBaseAsset_) {\n require(path[0] == underlyingAsset, \"RiskFund: swap path must start with the underlying asset\");\n require(\n path[path.length - 1] == convertibleBaseAsset_,\n \"RiskFund: finally path must be convertible base asset\"\n );\n address pancakeSwapRouter_ = pancakeSwapRouter;\n IERC20Upgradeable(underlyingAsset).approveOrRevert(pancakeSwapRouter_, 0);\n IERC20Upgradeable(underlyingAsset).approveOrRevert(pancakeSwapRouter_, balanceOfUnderlyingAsset);\n uint256[] memory amounts = IPancakeswapV2Router(pancakeSwapRouter_).swapExactTokensForTokens(\n balanceOfUnderlyingAsset,\n amountOutMin,\n path,\n address(this),\n block.timestamp\n );\n totalAmount = amounts[path.length - 1];\n } else {\n totalAmount = balanceOfUnderlyingAsset;\n }\n\n return totalAmount;\n }\n}\n" + }, + "contracts/Shortfall/Shortfall.sol": { + "content": "/// @notice SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { ReentrancyGuardUpgradeable } from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"../ComptrollerInterface.sol\";\nimport { IRiskFund } from \"../RiskFund/IRiskFund.sol\";\nimport { PoolRegistry } from \"../Pool/PoolRegistry.sol\";\nimport { PoolRegistryInterface } from \"../Pool/PoolRegistryInterface.sol\";\nimport { TokenDebtTracker } from \"../lib/TokenDebtTracker.sol\";\nimport { ensureNonzeroAddress } from \"../lib/validators.sol\";\nimport { EXP_SCALE } from \"../lib/constants.sol\";\n\n/**\n * @title Shortfall\n * @author Venus\n * @notice Shortfall is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset`\n * is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value.\n * This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner\n * is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise,\n * if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the\n * risk fund in exchange for paying off all the pool's bad debt.\n */\ncontract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGuardUpgradeable, TokenDebtTracker {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /// @notice Type of auction\n enum AuctionType {\n LARGE_POOL_DEBT,\n LARGE_RISK_FUND\n }\n\n /// @notice Status of auction\n enum AuctionStatus {\n NOT_STARTED,\n STARTED,\n ENDED\n }\n\n /// @notice Auction metadata\n struct Auction {\n uint256 startBlock;\n AuctionType auctionType;\n AuctionStatus status;\n VToken[] markets;\n uint256 seizedRiskFund;\n address highestBidder;\n uint256 highestBidBps;\n uint256 highestBidBlock;\n uint256 startBidBps;\n mapping(VToken => uint256) marketDebt;\n mapping(VToken => uint256) bidAmount;\n }\n\n /// @dev Max basis points i.e., 100%\n uint256 private constant MAX_BPS = 10000;\n\n uint256 private constant DEFAULT_NEXT_BIDDER_BLOCK_LIMIT = 100;\n\n uint256 private constant DEFAULT_WAIT_FOR_FIRST_BIDDER = 100;\n\n uint256 private constant DEFAULT_INCENTIVE_BPS = 1000; // 10%\n\n /// @notice Pool registry address\n address public poolRegistry;\n\n /// @notice Risk fund address\n IRiskFund public riskFund;\n\n /// @notice Minimum USD debt in pool for shortfall to trigger\n uint256 public minimumPoolBadDebt;\n\n /// @notice Incentive to auction participants, initial value set to 1000 or 10%\n uint256 public incentiveBps;\n\n /// @notice Time to wait for next bidder. Initially waits for 100 blocks\n uint256 public nextBidderBlockLimit;\n\n /// @notice Boolean of if auctions are paused\n bool public auctionsPaused;\n\n /// @notice Time to wait for first bidder. Initially waits for 100 blocks\n uint256 public waitForFirstBidder;\n\n /// @notice Auctions for each pool\n mapping(address => Auction) public auctions;\n\n /// @notice Emitted when a auction starts\n event AuctionStarted(\n address indexed comptroller,\n uint256 auctionStartBlock,\n AuctionType auctionType,\n VToken[] markets,\n uint256[] marketsDebt,\n uint256 seizedRiskFund,\n uint256 startBidBps\n );\n\n /// @notice Emitted when a bid is placed\n event BidPlaced(address indexed comptroller, uint256 auctionStartBlock, uint256 bidBps, address indexed bidder);\n\n /// @notice Emitted when a auction is completed\n event AuctionClosed(\n address indexed comptroller,\n uint256 auctionStartBlock,\n address indexed highestBidder,\n uint256 highestBidBps,\n uint256 seizedRiskFind,\n VToken[] markets,\n uint256[] marketDebt\n );\n\n /// @notice Emitted when a auction is restarted\n event AuctionRestarted(address indexed comptroller, uint256 auctionStartBlock);\n\n /// @notice Emitted when pool registry address is updated\n event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry);\n\n /// @notice Emitted when minimum pool bad debt is updated\n event MinimumPoolBadDebtUpdated(uint256 oldMinimumPoolBadDebt, uint256 newMinimumPoolBadDebt);\n\n /// @notice Emitted when wait for first bidder block count is updated\n event WaitForFirstBidderUpdated(uint256 oldWaitForFirstBidder, uint256 newWaitForFirstBidder);\n\n /// @notice Emitted when next bidder block limit is updated\n event NextBidderBlockLimitUpdated(uint256 oldNextBidderBlockLimit, uint256 newNextBidderBlockLimit);\n\n /// @notice Emitted when incentiveBps is updated\n event IncentiveBpsUpdated(uint256 oldIncentiveBps, uint256 newIncentiveBps);\n\n /// @notice Emitted when auctions are paused\n event AuctionsPaused(address sender);\n\n /// @notice Emitted when auctions are unpaused\n event AuctionsResumed(address sender);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\n /**\n * @notice Initialize the shortfall contract\n * @param riskFund_ RiskFund contract address\n * @param minimumPoolBadDebt_ Minimum bad debt in base asset for a pool to start auction\n * @param accessControlManager_ AccessControlManager contract address\n * @custom:error ZeroAddressNotAllowed is thrown when convertible base asset address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when risk fund address is zero\n */\n function initialize(\n IRiskFund riskFund_,\n uint256 minimumPoolBadDebt_,\n address accessControlManager_\n ) external initializer {\n ensureNonzeroAddress(address(riskFund_));\n require(minimumPoolBadDebt_ != 0, \"invalid minimum pool bad debt\");\n\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n __ReentrancyGuard_init();\n __TokenDebtTracker_init();\n minimumPoolBadDebt = minimumPoolBadDebt_;\n riskFund = riskFund_;\n waitForFirstBidder = DEFAULT_WAIT_FOR_FIRST_BIDDER;\n nextBidderBlockLimit = DEFAULT_NEXT_BIDDER_BLOCK_LIMIT;\n incentiveBps = DEFAULT_INCENTIVE_BPS;\n auctionsPaused = false;\n }\n\n /**\n * @notice Place a bid greater than the previous in an ongoing auction\n * @param comptroller Comptroller address of the pool\n * @param bidBps The bid percent of the risk fund or bad debt depending on auction type\n * @param auctionStartBlock The block number when auction started\n * @custom:event Emits BidPlaced event on success\n */\n function placeBid(\n address comptroller,\n uint256 bidBps,\n uint256 auctionStartBlock\n ) external nonReentrant {\n Auction storage auction = auctions[comptroller];\n\n require(auction.startBlock == auctionStartBlock, \"auction has been restarted\");\n require(_isStarted(auction), \"no on-going auction\");\n require(!_isStale(auction), \"auction is stale, restart it\");\n require(bidBps > 0, \"basis points cannot be zero\");\n require(bidBps <= MAX_BPS, \"basis points cannot be more than 10000\");\n require(\n (auction.auctionType == AuctionType.LARGE_POOL_DEBT &&\n ((auction.highestBidder != address(0) && bidBps > auction.highestBidBps) ||\n (auction.highestBidder == address(0) && bidBps >= auction.startBidBps))) ||\n (auction.auctionType == AuctionType.LARGE_RISK_FUND &&\n ((auction.highestBidder != address(0) && bidBps < auction.highestBidBps) ||\n (auction.highestBidder == address(0) && bidBps <= auction.startBidBps))),\n \"your bid is not the highest\"\n );\n\n uint256 marketsCount = auction.markets.length;\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = VToken(address(auction.markets[i]));\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\n\n if (auction.highestBidder != address(0)) {\n _transferOutOrTrackDebt(erc20, auction.highestBidder, auction.bidAmount[auction.markets[i]]);\n }\n uint256 balanceBefore = erc20.balanceOf(address(this));\n\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\n uint256 currentBidAmount = ((auction.marketDebt[auction.markets[i]] * bidBps) / MAX_BPS);\n erc20.safeTransferFrom(msg.sender, address(this), currentBidAmount);\n } else {\n erc20.safeTransferFrom(msg.sender, address(this), auction.marketDebt[auction.markets[i]]);\n }\n\n uint256 balanceAfter = erc20.balanceOf(address(this));\n auction.bidAmount[auction.markets[i]] = balanceAfter - balanceBefore;\n }\n\n auction.highestBidder = msg.sender;\n auction.highestBidBps = bidBps;\n auction.highestBidBlock = block.number;\n\n emit BidPlaced(comptroller, auction.startBlock, bidBps, msg.sender);\n }\n\n /**\n * @notice Close an auction\n * @param comptroller Comptroller address of the pool\n * @custom:event Emits AuctionClosed event on successful close\n */\n function closeAuction(address comptroller) external nonReentrant {\n Auction storage auction = auctions[comptroller];\n\n require(_isStarted(auction), \"no on-going auction\");\n require(\n block.number > auction.highestBidBlock + nextBidderBlockLimit && auction.highestBidder != address(0),\n \"waiting for next bidder. cannot close auction\"\n );\n\n uint256 marketsCount = auction.markets.length;\n uint256[] memory marketsDebt = new uint256[](marketsCount);\n\n auction.status = AuctionStatus.ENDED;\n\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = VToken(address(auction.markets[i]));\n IERC20Upgradeable erc20 = IERC20Upgradeable(address(vToken.underlying()));\n\n uint256 balanceBefore = erc20.balanceOf(address(auction.markets[i]));\n erc20.safeTransfer(address(auction.markets[i]), auction.bidAmount[auction.markets[i]]);\n uint256 balanceAfter = erc20.balanceOf(address(auction.markets[i]));\n marketsDebt[i] = balanceAfter - balanceBefore;\n\n auction.markets[i].badDebtRecovered(marketsDebt[i]);\n }\n\n uint256 riskFundBidAmount;\n\n if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) {\n riskFundBidAmount = auction.seizedRiskFund;\n } else {\n riskFundBidAmount = (auction.seizedRiskFund * auction.highestBidBps) / MAX_BPS;\n }\n\n address convertibleBaseAsset = riskFund.convertibleBaseAsset();\n\n uint256 transferredAmount = riskFund.transferReserveForAuction(comptroller, riskFundBidAmount);\n _transferOutOrTrackDebt(IERC20Upgradeable(convertibleBaseAsset), auction.highestBidder, riskFundBidAmount);\n\n emit AuctionClosed(\n comptroller,\n auction.startBlock,\n auction.highestBidder,\n auction.highestBidBps,\n transferredAmount,\n auction.markets,\n marketsDebt\n );\n }\n\n /**\n * @notice Start a auction when there is not currently one active\n * @param comptroller Comptroller address of the pool\n * @custom:event Emits AuctionStarted event on success\n * @custom:event Errors if auctions are paused\n */\n function startAuction(address comptroller) external nonReentrant {\n require(!auctionsPaused, \"Auctions are paused\");\n _startAuction(comptroller);\n }\n\n /**\n * @notice Restart an auction\n * @param comptroller Address of the pool\n * @custom:event Emits AuctionRestarted event on successful restart\n */\n function restartAuction(address comptroller) external nonReentrant {\n Auction storage auction = auctions[comptroller];\n\n require(!auctionsPaused, \"auctions are paused\");\n require(_isStarted(auction), \"no on-going auction\");\n require(_isStale(auction), \"you need to wait for more time for first bidder\");\n\n auction.status = AuctionStatus.ENDED;\n\n emit AuctionRestarted(comptroller, auction.startBlock);\n _startAuction(comptroller);\n }\n\n /**\n * @notice Update next bidder block limit which is used determine when an auction can be closed\n * @param _nextBidderBlockLimit New next bidder block limit\n * @custom:event Emits NextBidderBlockLimitUpdated on success\n * @custom:access Restricted by ACM\n */\n function updateNextBidderBlockLimit(uint256 _nextBidderBlockLimit) external {\n _checkAccessAllowed(\"updateNextBidderBlockLimit(uint256)\");\n require(_nextBidderBlockLimit != 0, \"_nextBidderBlockLimit must not be 0\");\n uint256 oldNextBidderBlockLimit = nextBidderBlockLimit;\n nextBidderBlockLimit = _nextBidderBlockLimit;\n emit NextBidderBlockLimitUpdated(oldNextBidderBlockLimit, _nextBidderBlockLimit);\n }\n\n /**\n * @notice Updates the incentive BPS\n * @param _incentiveBps New incentive BPS\n * @custom:event Emits IncentiveBpsUpdated on success\n * @custom:access Restricted by ACM\n */\n function updateIncentiveBps(uint256 _incentiveBps) external {\n _checkAccessAllowed(\"updateIncentiveBps(uint256)\");\n require(_incentiveBps != 0, \"incentiveBps must not be 0\");\n uint256 oldIncentiveBps = incentiveBps;\n incentiveBps = _incentiveBps;\n emit IncentiveBpsUpdated(oldIncentiveBps, _incentiveBps);\n }\n\n /**\n * @notice Update minimum pool bad debt to start auction\n * @param _minimumPoolBadDebt Minimum bad debt in BUSD for a pool to start auction\n * @custom:event Emits MinimumPoolBadDebtUpdated on success\n * @custom:access Restricted by ACM\n */\n function updateMinimumPoolBadDebt(uint256 _minimumPoolBadDebt) external {\n _checkAccessAllowed(\"updateMinimumPoolBadDebt(uint256)\");\n uint256 oldMinimumPoolBadDebt = minimumPoolBadDebt;\n minimumPoolBadDebt = _minimumPoolBadDebt;\n emit MinimumPoolBadDebtUpdated(oldMinimumPoolBadDebt, _minimumPoolBadDebt);\n }\n\n /**\n * @notice Update wait for first bidder block count. If the first bid is not made within this limit, the auction is closed and needs to be restarted\n * @param _waitForFirstBidder New wait for first bidder block count\n * @custom:event Emits WaitForFirstBidderUpdated on success\n * @custom:access Restricted by ACM\n */\n function updateWaitForFirstBidder(uint256 _waitForFirstBidder) external {\n _checkAccessAllowed(\"updateWaitForFirstBidder(uint256)\");\n uint256 oldWaitForFirstBidder = waitForFirstBidder;\n waitForFirstBidder = _waitForFirstBidder;\n emit WaitForFirstBidderUpdated(oldWaitForFirstBidder, _waitForFirstBidder);\n }\n\n /**\n * @notice Update the pool registry this shortfall supports\n * @dev After Pool Registry is deployed we need to set the pool registry address\n * @param poolRegistry_ Address of pool registry contract\n * @custom:event Emits PoolRegistryUpdated on success\n * @custom:access Restricted to owner\n * @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\n */\n function updatePoolRegistry(address poolRegistry_) external onlyOwner {\n ensureNonzeroAddress(poolRegistry_);\n address oldPoolRegistry = poolRegistry;\n poolRegistry = poolRegistry_;\n emit PoolRegistryUpdated(oldPoolRegistry, poolRegistry_);\n }\n\n /**\n * @notice Pause auctions. This disables starting new auctions but lets the current auction finishes\n * @custom:event Emits AuctionsPaused on success\n * @custom:error Errors is auctions are paused\n * @custom:access Restricted by ACM\n */\n function pauseAuctions() external {\n _checkAccessAllowed(\"pauseAuctions()\");\n require(!auctionsPaused, \"Auctions are already paused\");\n auctionsPaused = true;\n emit AuctionsPaused(msg.sender);\n }\n\n /**\n * @notice Resume paused auctions.\n * @custom:event Emits AuctionsResumed on success\n * @custom:error Errors is auctions are active\n * @custom:access Restricted by ACM\n */\n function resumeAuctions() external {\n _checkAccessAllowed(\"resumeAuctions()\");\n require(auctionsPaused, \"Auctions are not paused\");\n auctionsPaused = false;\n emit AuctionsResumed(msg.sender);\n }\n\n /**\n * @notice Start a auction when there is not currently one active\n * @param comptroller Comptroller address of the pool\n */\n function _startAuction(address comptroller) internal {\n PoolRegistryInterface.VenusPool memory pool = PoolRegistry(poolRegistry).getPoolByComptroller(comptroller);\n require(pool.comptroller == comptroller, \"comptroller doesn't exist pool registry\");\n\n Auction storage auction = auctions[comptroller];\n require(\n auction.status == AuctionStatus.NOT_STARTED || auction.status == AuctionStatus.ENDED,\n \"auction is on-going\"\n );\n\n auction.highestBidBps = 0;\n auction.highestBidBlock = 0;\n\n uint256 marketsCount = auction.markets.length;\n for (uint256 i; i < marketsCount; ++i) {\n VToken vToken = auction.markets[i];\n auction.marketDebt[vToken] = 0;\n }\n\n delete auction.markets;\n\n VToken[] memory vTokens = _getAllMarkets(comptroller);\n marketsCount = vTokens.length;\n ResilientOracleInterface priceOracle = _getPriceOracle(comptroller);\n uint256 poolBadDebt;\n\n uint256[] memory marketsDebt = new uint256[](marketsCount);\n auction.markets = new VToken[](marketsCount);\n\n for (uint256 i; i < marketsCount; ++i) {\n uint256 marketBadDebt = vTokens[i].badDebt();\n\n priceOracle.updatePrice(address(vTokens[i]));\n uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / EXP_SCALE;\n\n poolBadDebt = poolBadDebt + usdValue;\n auction.markets[i] = vTokens[i];\n auction.marketDebt[vTokens[i]] = marketBadDebt;\n marketsDebt[i] = marketBadDebt;\n }\n\n require(poolBadDebt >= minimumPoolBadDebt, \"pool bad debt is too low\");\n\n priceOracle.updateAssetPrice(riskFund.convertibleBaseAsset());\n uint256 riskFundBalance = (priceOracle.getPrice(riskFund.convertibleBaseAsset()) *\n riskFund.getPoolsBaseAssetReserves(comptroller)) / EXP_SCALE;\n uint256 remainingRiskFundBalance = riskFundBalance;\n uint256 badDebtPlusIncentive = poolBadDebt + ((poolBadDebt * incentiveBps) / MAX_BPS);\n if (badDebtPlusIncentive >= riskFundBalance) {\n auction.startBidBps =\n (MAX_BPS * MAX_BPS * remainingRiskFundBalance) /\n (poolBadDebt * (MAX_BPS + incentiveBps));\n remainingRiskFundBalance = 0;\n auction.auctionType = AuctionType.LARGE_POOL_DEBT;\n } else {\n uint256 maxSeizeableRiskFundBalance = badDebtPlusIncentive;\n\n remainingRiskFundBalance = remainingRiskFundBalance - maxSeizeableRiskFundBalance;\n auction.auctionType = AuctionType.LARGE_RISK_FUND;\n auction.startBidBps = MAX_BPS;\n }\n\n auction.seizedRiskFund = riskFundBalance - remainingRiskFundBalance;\n auction.startBlock = block.number;\n auction.status = AuctionStatus.STARTED;\n auction.highestBidder = address(0);\n\n emit AuctionStarted(\n comptroller,\n auction.startBlock,\n auction.auctionType,\n auction.markets,\n marketsDebt,\n auction.seizedRiskFund,\n auction.startBidBps\n );\n }\n\n /**\n * @dev Returns the price oracle of the pool\n * @param comptroller Address of the pool's comptroller\n * @return oracle The pool's price oracle\n */\n function _getPriceOracle(address comptroller) internal view returns (ResilientOracleInterface) {\n return ResilientOracleInterface(ComptrollerViewInterface(comptroller).oracle());\n }\n\n /**\n * @dev Returns all markets of the pool\n * @param comptroller Address of the pool's comptroller\n * @return markets The pool's markets as VToken array\n */\n function _getAllMarkets(address comptroller) internal view returns (VToken[] memory) {\n return ComptrollerInterface(comptroller).getAllMarkets();\n }\n\n /**\n * @dev Checks if the auction has started\n * @param auction The auction to query the status for\n * @return True if the auction has started\n */\n function _isStarted(Auction storage auction) internal view returns (bool) {\n return auction.status == AuctionStatus.STARTED;\n }\n\n /**\n * @dev Checks if the auction is stale, i.e. there's no bidder and the auction\n * was started more than waitForFirstBidder blocks ago.\n * @param auction The auction to query the status for\n * @return True if the auction is stale\n */\n function _isStale(Auction storage auction) internal view returns (bool) {\n bool noBidder = auction.highestBidder == address(0);\n return noBidder && (block.number > auction.startBlock + waitForFirstBidder);\n }\n}\n" + }, + "contracts/test/ComptrollerHarness.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { Comptroller } from \"../Comptroller.sol\";\n\ncontract ComptrollerHarness is Comptroller {\n uint256 public blockNumber;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address _poolRegistry) Comptroller(_poolRegistry) {}\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\ncontract EchoTypesComptroller {\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(uint256[] memory u) public pure returns (uint256[] memory) {\n return u;\n }\n\n function reverty() public pure {\n require(false, \"gotcha sucka\");\n }\n}\n" + }, + "contracts/test/ComptrollerScenario.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { Comptroller } from \"../Comptroller.sol\";\nimport { VToken } from \"../VToken.sol\";\n\ncontract ComptrollerScenario is Comptroller {\n uint256 public blockNumber;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address _poolRegistry) Comptroller(_poolRegistry) {}\n\n function fastForward(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 unlist(VToken vToken) public {\n markets[address(vToken)].isListed = false;\n }\n\n function membershipLength(VToken vToken) public view returns (uint256) {\n return accountAssets[address(vToken)].length;\n }\n}\n" + }, + "contracts/test/Mocks/MockPriceOracle.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { BinanceOracle } from \"@venusprotocol/oracle/contracts/oracles/BinanceOracle.sol\";\nimport { ChainlinkOracle } from \"@venusprotocol/oracle/contracts/oracles/ChainlinkOracle.sol\";\n\nimport { VToken } from \"../../VToken.sol\";\n\ncontract MockPriceOracle is ResilientOracleInterface {\n mapping(address => uint256) public assetPrices;\n\n //set price in 6 decimal precision\n // solhint-disable-next-line no-empty-blocks\n constructor() {}\n\n function setPrice(address asset, uint256 price) external {\n assetPrices[asset] = price;\n }\n\n // solhint-disable-next-line no-empty-blocks\n function updatePrice(address vToken) external override {}\n\n // solhint-disable-next-line no-empty-blocks\n function updateAssetPrice(address asset) external override {}\n\n function getPrice(address asset) external view returns (uint256) {\n return assetPrices[asset];\n }\n\n //https://compound.finance/docs/prices\n function getUnderlyingPrice(address vToken) public view override returns (uint256) {\n return assetPrices[VToken(vToken).underlying()];\n }\n}\n" + }, + "contracts/test/UpgradedVToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { AccessControlManager } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol\";\n\nimport { VToken } from \"../VToken.sol\";\nimport { ComptrollerInterface } from \"../ComptrollerInterface.sol\";\nimport { InterestRateModel } from \"../InterestRateModel.sol\";\n\n/**\n * @title Venus's VToken Contract\n * @notice VTokens which wrap an EIP-20 underlying and are immutable\n * @author Venus\n */\ncontract UpgradedVToken is VToken {\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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param riskManagement Addresses of risk fund contracts\n */\n\n /// @notice We added this new function to test contract upgrade\n function version() external pure returns (uint256) {\n return 2;\n }\n\n function initializeV2(\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 accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) public reinitializer(2) {\n super._initialize(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_,\n accessControlManager_,\n riskManagement,\n reserveFactorMantissa_\n );\n }\n\n function getTokenUnderlying() public view returns (address) {\n return underlying;\n }\n}\n" + }, + "contracts/test/VTokenHarness.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.10;\n\nimport { AccessControlManager } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol\";\n\nimport { VToken } from \"../VToken.sol\";\nimport { InterestRateModel } from \"../InterestRateModel.sol\";\n\ncontract VTokenHarness is VToken {\n uint256 public blockNumber;\n uint256 public harnessExchangeRate;\n bool public harnessExchangeRateStored;\n\n mapping(address => bool) public failTransferToAddresses;\n\n function harnessSetAccrualBlockNumber(uint256 accrualBlockNumber_) external {\n accrualBlockNumber = accrualBlockNumber_;\n }\n\n function harnessSetBlockNumber(uint256 newBlockNumber) external {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint256 blocks) external {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint256 amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetTotalSupply(uint256 totalSupply_) external {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint256 totalBorrows_) external {\n totalBorrows = totalBorrows_;\n }\n\n function harnessSetTotalReserves(uint256 totalReserves_) external {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(\n uint256 totalSupply_,\n uint256 totalBorrows_,\n uint256 totalReserves_\n ) external {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint256 exchangeRate) external {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address to_, bool fail_) external {\n failTransferToAddresses[to_] = fail_;\n }\n\n function harnessMintFresh(address account, uint256 mintAmount) external {\n super._mintFresh(account, account, mintAmount);\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint256 vTokenAmount,\n uint256 underlyingAmount\n ) external {\n super._redeemFresh(account, vTokenAmount, underlyingAmount);\n }\n\n function harnessSetAccountBorrows(\n address account,\n uint256 principal,\n uint256 interestIndex\n ) external {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint256 borrowIndex_) external {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint256 borrowAmount) external {\n _borrowFresh(account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(\n address payer,\n address account,\n uint256 repayAmount\n ) external {\n _repayBorrowFresh(payer, account, repayAmount);\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VToken vTokenCollateral,\n bool skipLiquidityCheck\n ) external {\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\n }\n\n function harnessReduceReservesFresh(uint256 amount) external {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint256 newReserveFactorMantissa) external {\n _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) external {\n _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessAccountBorrows(address account) external view returns (uint256 principal, uint256 interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function getBorrowRateMaxMantissa() external pure returns (uint256) {\n return MAX_BORROW_RATE_MANTISSA;\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallPreBorrowHook(uint256 amount) public {\n comptroller.preBorrowHook(address(this), msg.sender, amount);\n }\n\n function _doTransferOut(address to, uint256 amount) internal override {\n require(failTransferToAddresses[to] == false, \"HARNESS_TOKEN_TRANSFER_OUT_FAILED\");\n return super._doTransferOut(to, amount);\n }\n\n function _exchangeRateStored() internal view override returns (uint256) {\n if (harnessExchangeRateStored) {\n return harnessExchangeRate;\n }\n return super._exchangeRateStored();\n }\n\n function _getBlockNumber() internal view override returns (uint256) {\n return blockNumber;\n }\n}\n" + }, + "contracts/VToken.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { SafeERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\nimport { VTokenInterface } from \"./VTokenInterfaces.sol\";\nimport { ComptrollerInterface, ComptrollerViewInterface } from \"./ComptrollerInterface.sol\";\nimport { TokenErrorReporter } from \"./ErrorReporter.sol\";\nimport { InterestRateModel } from \"./InterestRateModel.sol\";\nimport { ExponentialNoError } from \"./ExponentialNoError.sol\";\nimport { IProtocolShareReserve } from \"./RiskFund/IProtocolShareReserve.sol\";\nimport { ensureNonzeroAddress } from \"./lib/validators.sol\";\n\n/**\n * @title VToken\n * @author Venus\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\n * the pool. The main actions a user regularly interacts with in a market are:\n\n- mint/redeem of vTokens;\n- transfer of vTokens;\n- borrow/repay a loan on an underlying asset;\n- liquidate a borrow or liquidate/heal an account.\n\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\n * a user may borrow up to a portion of their collateral determined by the market’s collateral factor. However, if their borrowed amount exceeds an amount\n * calculated using the market’s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\n * pay off interest accrued on the borrow.\n * \n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\n * Both functions settle all of an account’s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\n */\ncontract VToken is\n Ownable2StepUpgradeable,\n AccessControlledV8,\n VTokenInterface,\n ExponentialNoError,\n TokenErrorReporter\n{\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\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 /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n // Note that the contract is upgradeable. Use initialize() or reinitializers\n // to set the state variables.\n _disableInitializers();\n }\n\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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param accessControlManager_ AccessControlManager contract address\n * @param riskManagement Addresses of risk & income related contracts\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\n * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\n */\n function initialize(\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 admin_,\n address accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) external initializer {\n ensureNonzeroAddress(admin_);\n\n // Initialize the market\n _initialize(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_,\n accessControlManager_,\n riskManagement,\n reserveFactorMantissa_\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 * @return success True if the transfer succeeded, reverts otherwise\n * @custom:event Emits Transfer event on success\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\n * @custom:access Not restricted\n */\n function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\n _transferTokens(msg.sender, 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 amount The number of tokens to transfer\n * @return success True if the transfer succeeded, reverts otherwise\n * @custom:event Emits Transfer event on success\n * @custom:error TransferNotAllowed is thrown if trying to transfer to self\n * @custom:access Not restricted\n */\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) external override nonReentrant returns (bool) {\n _transferTokens(msg.sender, src, dst, amount);\n return true;\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 (uint256.max means infinite)\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function approve(address spender, uint256 amount) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n transferAllowances[src][spender] = amount;\n emit Approval(src, spender, amount);\n return true;\n }\n\n /**\n * @notice Increase approval for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param addedValue The number of additional tokens spender can transfer\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n uint256 newAllowance = transferAllowances[src][spender];\n newAllowance += addedValue;\n transferAllowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n return true;\n }\n\n /**\n * @notice Decreases approval for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param subtractedValue The number of tokens to remove from total approval\n * @return success Whether or not the approval succeeded\n * @custom:event Emits Approval event\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\n ensureNonzeroAddress(spender);\n\n address src = msg.sender;\n uint256 currentAllowance = transferAllowances[src][spender];\n require(currentAllowance >= subtractedValue, \"decreased allowance below zero\");\n unchecked {\n currentAllowance -= subtractedValue;\n }\n\n transferAllowances[src][spender] = currentAllowance;\n\n emit Approval(src, spender, currentAllowance);\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 amount The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external override returns (uint256) {\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\n return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return totalBorrows The total borrows with interest\n */\n function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\n accrueInterest();\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 borrowBalance The calculated balance\n */\n function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\n accrueInterest();\n return _borrowBalanceStored(account);\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n _mintFresh(msg.sender, msg.sender, mintAmount);\n return NO_ERROR;\n }\n\n /**\n * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param minter User whom the supply will be attributed to\n * @param mintAmount The amount of the underlying asset to supply\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\n * @custom:access Not restricted\n * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\n */\n function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\n ensureNonzeroAddress(minter);\n\n accrueInterest();\n // _mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n _mintFresh(msg.sender, minter, mintAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\n * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\n * @custom:access Not restricted\n */\n function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\n _redeemFresh(msg.sender, redeemTokens, 0);\n return NO_ERROR;\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 receive from redeeming vTokens\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n */\n function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _redeemFresh emits redeem-specific logs on errors, so we don't need to\n _redeemFresh(msg.sender, 0, redeemAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits Borrow event; may emit AccrueInterest\n * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\n * @custom:access Not restricted\n */\n function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\n _borrowFresh(msg.sender, borrowAmount);\n return NO_ERROR;\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\n return NO_ERROR;\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, or type(uint256).max for the full outstanding amount\n * @return error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits RepayBorrow event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\n accrueInterest();\n // _repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n _repayBorrowFresh(msg.sender, borrower, repayAmount);\n return NO_ERROR;\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 error Always NO_ERROR for compatibility with Venus core tooling\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\n * @custom:access Not restricted\n */\n function liquidateBorrow(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external override returns (uint256) {\n _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\n return NO_ERROR;\n }\n\n /**\n * @notice sets protocol share accumulated from liquidations\n * @dev must be equal or less than liquidation incentive - 1\n * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\n * @custom:event Emits NewProtocolSeizeShare event on success\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\n * @custom:access Controlled by AccessControlManager\n */\n function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\n _checkAccessAllowed(\"setProtocolSeizeShare(uint256)\");\n uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\n if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\n revert ProtocolSeizeShareTooBig();\n }\n\n uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\n protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\n emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\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 * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\n * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\n * @custom:access Controlled by AccessControlManager\n */\n function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\n _checkAccessAllowed(\"setReserveFactor(uint256)\");\n\n accrueInterest();\n _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\n * @param reduceAmount Amount of reduction to reserves\n * @custom:event Emits ReservesReduced event; may emit AccrueInterest\n * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\n * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\n * @custom:access Not restricted\n */\n function reduceReserves(uint256 reduceAmount) external override nonReentrant {\n accrueInterest();\n _reduceReservesFresh(reduceAmount);\n }\n\n /**\n * @notice The sender adds to reserves.\n * @param addAmount The amount of underlying token to add as reserves\n * @custom:event Emits ReservesAdded event; may emit AccrueInterest\n * @custom:access Not restricted\n */\n function addReserves(uint256 addAmount) external override nonReentrant {\n accrueInterest();\n _addReservesFresh(addAmount);\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 * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\n * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\n * @custom:access Controlled by AccessControlManager\n */\n function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\n _checkAccessAllowed(\"setInterestRateModel(address)\");\n\n accrueInterest();\n _setInterestRateModelFresh(newInterestRateModel);\n }\n\n /**\n * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\n * \"forgiving\" the borrower. Healing is a situation that should rarely happen. However, some pools\n * may list risky assets or be configured improperly – we want to still handle such cases gracefully.\n * We assume that Comptroller does the seizing, so this function is only available to Comptroller.\n * @dev This function does not call any Comptroller hooks (like \"healAllowed\"), because we assume\n * the Comptroller does all the necessary checks before calling this function.\n * @param payer account who repays the debt\n * @param borrower account to heal\n * @param repayAmount amount to repay\n * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\n * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\n * @custom:access Only Comptroller\n */\n function healBorrow(\n address payer,\n address borrower,\n uint256 repayAmount\n ) external override nonReentrant {\n if (repayAmount != 0) {\n comptroller.preRepayHook(address(this), borrower);\n }\n\n if (msg.sender != address(comptroller)) {\n revert HealBorrowUnauthorized();\n }\n\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n uint256 totalBorrowsNew = totalBorrows;\n\n uint256 actualRepayAmount;\n if (repayAmount != 0) {\n // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\n // We violate checks-effects-interactions here to account for tokens that take transfer fees\n actualRepayAmount = _doTransferIn(payer, repayAmount);\n totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\n emit RepayBorrow(\n payer,\n borrower,\n actualRepayAmount,\n accountBorrowsPrev - actualRepayAmount,\n totalBorrowsNew\n );\n }\n\n // The transaction will fail if trying to repay too much\n uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\n if (badDebtDelta != 0) {\n uint256 badDebtOld = badDebt;\n uint256 badDebtNew = badDebtOld + badDebtDelta;\n totalBorrowsNew = totalBorrowsNew - badDebtDelta;\n badDebt = badDebtNew;\n\n // We treat healing as \"repayment\", where vToken is the payer\n emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\n emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\n }\n\n accountBorrows[borrower].principal = 0;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n emit HealBorrow(payer, borrower, repayAmount);\n }\n\n /**\n * @notice The extended version of liquidations, callable only by Comptroller. May skip\n * the close factor check. The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\n * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\n * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\n * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\n * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\n * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\n * @custom:access Only Comptroller\n */\n function forceLiquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) external override {\n if (msg.sender != address(comptroller)) {\n revert ForceLiquidateBorrowUnauthorized();\n }\n _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\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 * @custom:event Emits Transfer, ReservesAdded events\n * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\n * @custom:access Not restricted\n */\n function seize(\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external override nonReentrant {\n _seize(msg.sender, liquidator, borrower, seizeTokens);\n }\n\n /**\n * @notice Updates bad debt\n * @dev Called only when bad debt is recovered from auction\n * @param recoveredAmount_ The amount of bad debt recovered\n * @custom:event Emits BadDebtRecovered event\n * @custom:access Only Shortfall contract\n */\n function badDebtRecovered(uint256 recoveredAmount_) external {\n require(msg.sender == shortfall, \"only shortfall contract can update bad debt\");\n require(recoveredAmount_ <= badDebt, \"more than bad debt recovered from auction\");\n\n uint256 badDebtOld = badDebt;\n uint256 badDebtNew = badDebtOld - recoveredAmount_;\n badDebt = badDebtNew;\n\n emit BadDebtRecovered(badDebtOld, badDebtNew);\n }\n\n /**\n * @notice Sets protocol share reserve contract address\n * @param protocolShareReserve_ The address of the protocol share reserve contract\n * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\n * @custom:access Only Governance\n */\n function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\n _setProtocolShareReserve(protocolShareReserve_);\n }\n\n /**\n * @notice Sets shortfall contract address\n * @param shortfall_ The address of the shortfall contract\n * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\n * @custom:access Only Governance\n */\n function setShortfallContract(address shortfall_) external onlyOwner {\n _setShortfallContract(shortfall_);\n }\n\n /**\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\n * @param token The address of the ERC-20 token to sweep\n * @custom:access Only Governance\n */\n function sweepToken(IERC20Upgradeable token) external override {\n require(msg.sender == owner(), \"VToken::sweepToken: only admin can sweep tokens\");\n require(address(token) != underlying, \"VToken::sweepToken: can not sweep underlying token\");\n uint256 balance = token.balanceOf(address(this));\n token.safeTransfer(owner(), balance);\n\n emit SweepToken(address(token));\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 amount The number of tokens allowed to be spent (type(uint256).max means infinite)\n */\n function allowance(address owner, address spender) external view override 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 amount The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view override 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 error Always NO_ERROR for compatibility with Venus core tooling\n * @return vTokenBalance User's balance of vTokens\n * @return borrowBalance Amount owed in terms of underlying\n * @return exchangeRate Stored exchange rate\n */\n function getAccountSnapshot(address account)\n external\n view\n override\n returns (\n uint256 error,\n uint256 vTokenBalance,\n uint256 borrowBalance,\n uint256 exchangeRate\n )\n {\n return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return cash The quantity of underlying asset owned by this contract\n */\n function getCash() external view override returns (uint256) {\n return _getCashPrior();\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return rate The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view override returns (uint256) {\n return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this v\n * @return rate The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view override returns (uint256) {\n return\n interestRateModel.getSupplyRate(\n _getCashPrior(),\n totalBorrows,\n totalReserves,\n reserveFactorMantissa,\n badDebt\n );\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 borrowBalance The calculated balance\n */\n function borrowBalanceStored(address account) external view override returns (uint256) {\n return _borrowBalanceStored(account);\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 exchangeRate Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() external view override returns (uint256) {\n return _exchangeRateStored();\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return exchangeRate Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public override nonReentrant returns (uint256) {\n accrueInterest();\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.\n * @return Always NO_ERROR\n * @custom:event Emits AccrueInterest event on success\n * @custom:access Not restricted\n */\n function accrueInterest() public virtual override returns (uint256) {\n /* Remember the initial block number */\n uint256 currentBlockNumber = _getBlockNumber();\n uint256 accrualBlockNumberPrior = accrualBlockNumber;\n\n /* Short-circuit accumulating 0 interest */\n if (accrualBlockNumberPrior == currentBlockNumber) {\n return NO_ERROR;\n }\n\n /* Read the previous values out of storage */\n uint256 cashPrior = _getCashPrior();\n uint256 borrowsPrior = totalBorrows;\n uint256 reservesPrior = totalReserves;\n uint256 borrowIndexPrior = borrowIndex;\n\n /* Calculate the current borrow interest rate */\n uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\n require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \"borrow rate is absurdly high\");\n\n /* Calculate the number of blocks elapsed since the last accrual */\n uint256 blockDelta = currentBlockNumber - accrualBlockNumberPrior;\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 = mul_(Exp({ mantissa: borrowRateMantissa }), blockDelta);\n uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\n uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\n uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\n Exp({ mantissa: reserveFactorMantissa }),\n interestAccumulated,\n reservesPrior\n );\n uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\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 NO_ERROR;\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 payer The address of the account which is sending the assets for supply\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 */\n function _mintFresh(\n address payer,\n address minter,\n uint256 mintAmount\n ) internal {\n /* Fail if mint not allowed */\n comptroller.preMintHook(address(this), minter, mintAmount);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert MintFreshnessCheck();\n }\n\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\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 * `_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 uint256 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 uint256 mintTokens = div_(actualMintAmount, exchangeRate);\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 * And write them into storage\n */\n totalSupply = totalSupply + mintTokens;\n uint256 balanceAfter = accountTokens[minter] + mintTokens;\n accountTokens[minter] = balanceAfter;\n\n /* We emit a Mint event, and a Transfer event */\n emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\n emit Transfer(address(0), minter, mintTokens);\n }\n\n /**\n * @notice User redeems vTokens in exchange for the underlying asset\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 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 */\n function _redeemFresh(\n address redeemer,\n uint256 redeemTokensIn,\n uint256 redeemAmountIn\n ) internal {\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \"one of redeemTokensIn or redeemAmountIn must be zero\");\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert RedeemFreshnessCheck();\n }\n\n /* exchangeRate = invoke Exchange Rate Stored() */\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\n\n uint256 redeemTokens;\n uint256 redeemAmount;\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 */\n redeemTokens = redeemTokensIn;\n } else {\n /*\n * We get the current exchange rate and calculate the amount to be redeemed:\n * redeemTokens = redeemAmountIn / exchangeRate\n */\n redeemTokens = div_(redeemAmountIn, exchangeRate);\n\n uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\n if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\n }\n\n // redeemAmount = exchangeRate * redeemTokens\n redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\n\n // Revert if amount is zero\n if (redeemAmount == 0) {\n revert(\"redeemAmount is zero\");\n }\n\n /* Fail if redeem not allowed */\n comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\n\n /* Fail gracefully if protocol has insufficient cash */\n if (_getCashPrior() - totalReserves < redeemAmount) {\n revert RedeemTransferOutNotPossible();\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We write the previously calculated values into storage.\n * Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\n */\n totalSupply = totalSupply - redeemTokens;\n uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\n accountTokens[redeemer] = balanceAfter;\n\n /*\n * We invoke _doTransferOut for the redeemer and the redeemAmount.\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 _doTransferOut(redeemer, redeemAmount);\n\n /* We emit a Transfer event, and a Redeem event */\n emit Transfer(redeemer, address(this), redeemTokens);\n emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\n }\n\n /**\n * @notice Users borrow assets from the protocol to their own address\n * @param borrower User who borrows the assets\n * @param borrowAmount The amount of the underlying asset to borrow\n */\n function _borrowFresh(address borrower, uint256 borrowAmount) internal {\n /* Fail if borrow not allowed */\n comptroller.preBorrowHook(address(this), borrower, borrowAmount);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert BorrowFreshnessCheck();\n }\n\n /* Fail gracefully if protocol has insufficient underlying cash */\n if (_getCashPrior() - totalReserves < borrowAmount) {\n revert BorrowCashNotAvailable();\n }\n\n /*\n * We calculate the new borrower and total borrow balances, failing on overflow:\n * accountBorrowNew = accountBorrow + borrowAmount\n * totalBorrowsNew = totalBorrows + borrowAmount\n */\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\n uint256 totalBorrowsNew = totalBorrows + borrowAmount;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We write the previously calculated values into storage.\n * Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\n `*/\n accountBorrows[borrower].principal = accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n /*\n * We invoke _doTransferOut for the borrower and the borrowAmount.\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(borrower, borrowAmount);\n\n /* We emit a Borrow event */\n emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\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 underlying tokens being returned, or type(uint256).max for the full outstanding amount\n * @return (uint) the actual repayment amount.\n */\n function _repayBorrowFresh(\n address payer,\n address borrower,\n uint256 repayAmount\n ) internal returns (uint256) {\n /* Fail if repayBorrow not allowed */\n comptroller.preRepayHook(address(this), borrower);\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert RepayBorrowFreshnessCheck();\n }\n\n /* We fetch the amount the borrower owes, with accumulated interest */\n uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\n\n uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\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 * 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 uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\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 uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\n uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\n\n /* We write the previously calculated values into storage */\n accountBorrows[borrower].principal = accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = totalBorrowsNew;\n\n /* We emit a RepayBorrow event */\n emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\n\n return actualRepayAmount;\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n */\n function _liquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) internal nonReentrant {\n accrueInterest();\n\n uint256 error = vTokenCollateral.accrueInterest();\n if (error != NO_ERROR) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n revert LiquidateAccrueCollateralInterestFailed(error);\n }\n\n // _liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\n _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\n }\n\n /**\n * @notice The liquidator liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param liquidator The address repaying the borrow and seizing collateral\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 * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\n * regardless of the account liquidity\n */\n function _liquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipLiquidityCheck\n ) internal {\n /* Fail if liquidate not allowed */\n comptroller.preLiquidateHook(\n address(this),\n address(vTokenCollateral),\n borrower,\n repayAmount,\n skipLiquidityCheck\n );\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != _getBlockNumber()) {\n revert LiquidateFreshnessCheck();\n }\n\n /* Verify vTokenCollateral market's block number equals current block number */\n if (vTokenCollateral.accrualBlockNumber() != _getBlockNumber()) {\n revert LiquidateCollateralFreshnessCheck();\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n revert LiquidateLiquidatorIsBorrower();\n }\n\n /* Fail if repayAmount = 0 */\n if (repayAmount == 0) {\n revert LiquidateCloseAmountIsZero();\n }\n\n /* Fail if repayAmount = type(uint256).max */\n if (repayAmount == type(uint256).max) {\n revert LiquidateCloseAmountIsUintMax();\n }\n\n /* Fail if repayBorrow fails */\n uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\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.liquidateCalculateSeizeTokens(\n address(this),\n address(vTokenCollateral),\n actualRepayAmount\n );\n require(amountSeizeError == 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, call _seize internally to avoid re-entrancy, otherwise make an external call\n if (address(vTokenCollateral) == address(this)) {\n _seize(address(this), liquidator, borrower, seizeTokens);\n } else {\n vTokenCollateral.seize(liquidator, borrower, seizeTokens);\n }\n\n /* We emit a LiquidateBorrow event */\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\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 * It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\n * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\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 */\n function _seize(\n address seizerContract,\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) internal {\n /* Fail if seize not allowed */\n comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n revert LiquidateSeizeLiquidatorIsBorrower();\n }\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 uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\n .liquidationIncentiveMantissa();\n uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\n uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\n uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\n Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\n uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\n uint256 totalReservesNew = totalReserves + protocolSeizeAmount;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the calculated values into storage */\n totalReserves = totalReservesNew;\n totalSupply = totalSupply - protocolSeizeTokens;\n accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\n accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\n\n /* Emit a Transfer event */\n emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\n emit Transfer(borrower, address(this), protocolSeizeTokens);\n emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);\n }\n\n function _setComptroller(ComptrollerInterface newComptroller) internal {\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\n /**\n * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\n * @dev Admin function to set a new reserve factor\n * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\n */\n function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\n // Verify market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert SetReserveFactorFreshCheck();\n }\n\n // Check newReserveFactor ≤ maxReserveFactor\n if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\n revert SetReserveFactorBoundsCheck();\n }\n\n uint256 oldReserveFactorMantissa = reserveFactorMantissa;\n reserveFactorMantissa = newReserveFactorMantissa;\n\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\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 actualAddAmount The actual amount added, excluding the potential token fees\n */\n function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\n // totalReserves + actualAddAmount\n uint256 totalReservesNew;\n uint256 actualAddAmount;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert AddReservesFactorFreshCheck(actualAddAmount);\n }\n\n actualAddAmount = _doTransferIn(msg.sender, addAmount);\n totalReservesNew = totalReserves + actualAddAmount;\n totalReserves = totalReservesNew;\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\n\n return actualAddAmount;\n }\n\n /**\n * @notice Reduces reserves by transferring to the protocol reserve contract\n * @dev Requires fresh interest accrual\n * @param reduceAmount Amount of reduction to reserves\n */\n function _reduceReservesFresh(uint256 reduceAmount) internal {\n // totalReserves - reduceAmount\n uint256 totalReservesNew;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert ReduceReservesFreshCheck();\n }\n\n // Fail gracefully if protocol has insufficient underlying cash\n if (_getCashPrior() < reduceAmount) {\n revert ReduceReservesCashNotAvailable();\n }\n\n // Check reduceAmount ≤ reserves[n] (totalReserves)\n if (reduceAmount > totalReserves) {\n revert ReduceReservesCashValidation();\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 // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\n _doTransferOut(protocolShareReserve, reduceAmount);\n\n // Update the pool asset's state in the protocol share reserve for the above transfer.\n IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);\n\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\n }\n\n /**\n * @notice updates the interest rate model (*requires fresh interest accrual)\n * @dev Admin function to update the interest rate model\n * @param newInterestRateModel the new interest rate model to use\n */\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\n // Used to store old model for use in the event that is emitted on success\n InterestRateModel oldInterestRateModel;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != _getBlockNumber()) {\n revert SetInterestRateModelFreshCheck();\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\n /*** Safe Token ***/\n\n /**\n * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\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 * @param from Sender of the underlying tokens\n * @param amount Amount of underlying to transfer\n * @return Actual amount received\n */\n function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n uint256 balanceBefore = token.balanceOf(address(this));\n token.safeTransferFrom(from, address(this), amount);\n uint256 balanceAfter = token.balanceOf(address(this));\n // Return the amount that was *actually* transferred\n return balanceAfter - balanceBefore;\n }\n\n /**\n * @dev Just a regular ERC-20 transfer, reverts on failure\n * @param to Receiver of the underlying tokens\n * @param amount Amount of underlying to transfer\n */\n function _doTransferOut(address to, uint256 amount) internal virtual {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n token.safeTransfer(to, amount);\n }\n\n /**\n * @notice Transfer `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 */\n function _transferTokens(\n address spender,\n address src,\n address dst,\n uint256 tokens\n ) internal {\n /* Fail if transfer not allowed */\n comptroller.preTransferHook(address(this), src, dst, tokens);\n\n /* Do not allow self-transfers */\n if (src == dst) {\n revert TransferNotAllowed();\n }\n\n /* Get the allowance, infinite for the account owner */\n uint256 startingAllowance;\n if (spender == src) {\n startingAllowance = type(uint256).max;\n } else {\n startingAllowance = transferAllowances[src][spender];\n }\n\n /* Do the calculations, checking for {under,over}flow */\n uint256 allowanceNew = startingAllowance - tokens;\n uint256 srcTokensNew = accountTokens[src] - tokens;\n uint256 dstTokensNew = accountTokens[dst] + tokens;\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n\n accountTokens[src] = srcTokensNew;\n accountTokens[dst] = dstTokensNew;\n\n /* Eat some of the allowance (if necessary) */\n if (startingAllowance != type(uint256).max) {\n transferAllowances[src][spender] = allowanceNew;\n }\n\n /* We emit a Transfer event */\n emit Transfer(src, dst, tokens);\n }\n\n /**\n * @notice Initialize the 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_ ERC-20 name of this token\n * @param symbol_ ERC-20 symbol of this token\n * @param decimals_ ERC-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param accessControlManager_ AccessControlManager contract address\n * @param riskManagement Addresses of risk & income related contracts\n * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\n */\n function _initialize(\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 admin_,\n address accessControlManager_,\n RiskManagementInit memory riskManagement,\n uint256 reserveFactorMantissa_\n ) internal onlyInitializing {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\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 _setComptroller(comptroller_);\n\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\n accrualBlockNumber = _getBlockNumber();\n borrowIndex = MANTISSA_ONE;\n\n // Set the interest rate model (depends on block number / borrow index)\n _setInterestRateModelFresh(interestRateModel_);\n\n _setReserveFactorFresh(reserveFactorMantissa_);\n\n name = name_;\n symbol = symbol_;\n decimals = decimals_;\n _setShortfallContract(riskManagement.shortfall);\n _setProtocolShareReserve(riskManagement.protocolShareReserve);\n protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\n\n // Set underlying and sanity check it\n underlying = underlying_;\n IERC20Upgradeable(underlying).totalSupply();\n\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\n _notEntered = true;\n _transferOwnership(admin_);\n }\n\n function _setShortfallContract(address shortfall_) internal {\n ensureNonzeroAddress(shortfall_);\n address oldShortfall = shortfall;\n shortfall = shortfall_;\n emit NewShortfallContract(oldShortfall, shortfall_);\n }\n\n function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\n ensureNonzeroAddress(protocolShareReserve_);\n address oldProtocolShareReserve = address(protocolShareReserve);\n protocolShareReserve = protocolShareReserve_;\n emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\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 virtual returns (uint256) {\n IERC20Upgradeable token = IERC20Upgradeable(underlying);\n return token.balanceOf(address(this));\n }\n\n /**\n * @dev Function to simply retrieve block number\n * This exists mainly for inheriting test contracts to stub this result.\n * @return Current block number\n */\n function _getBlockNumber() internal view virtual returns (uint256) {\n return block.number;\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 borrowBalance the calculated balance\n */\n function _borrowBalanceStored(address account) internal view returns (uint256) {\n /* Get borrowBalance and borrowIndex */\n BorrowSnapshot memory 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 0;\n }\n\n /* Calculate new borrow balance using the interest index:\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\n */\n uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\n\n return principalTimesIndex / borrowSnapshot.interestIndex;\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 exchangeRate Calculated exchange rate scaled by 1e18\n */\n function _exchangeRateStored() internal view virtual returns (uint256) {\n uint256 _totalSupply = totalSupply;\n if (_totalSupply == 0) {\n /*\n * If there are no tokens minted:\n * exchangeRate = initialExchangeRate\n */\n return initialExchangeRateMantissa;\n }\n /*\n * Otherwise:\n * exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\n */\n uint256 totalCash = _getCashPrior();\n uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\n uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\n\n return exchangeRate;\n }\n}\n" + }, + "contracts/VTokenInterfaces.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.13;\n\nimport { IERC20Upgradeable } from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\n\nimport { ComptrollerInterface } from \"./ComptrollerInterface.sol\";\nimport { InterestRateModel } from \"./InterestRateModel.sol\";\n\n/**\n * @title VTokenStorage\n * @author Venus\n * @notice Storage layout used by the `VToken` contract\n */\n// solhint-disable-next-line max-states-count\ncontract VTokenStorage {\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 uint256 principal;\n uint256 interestIndex;\n }\n\n /**\n * @dev Guard variable for re-entrancy checks\n */\n bool internal _notEntered;\n\n /**\n * @notice Underlying asset for this VToken\n */\n address public underlying;\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 Protocol share Reserve contract address\n */\n address payable public protocolShareReserve;\n\n // Maximum borrow rate that can ever be applied (.0005% / block)\n uint256 internal constant MAX_BORROW_RATE_MANTISSA = 0.0005e16;\n\n // Maximum fraction of interest that can be set aside for reserves\n uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\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 // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\n uint256 internal initialExchangeRateMantissa;\n\n /**\n * @notice Fraction of interest currently set aside for reserves\n */\n uint256 public reserveFactorMantissa;\n\n /**\n * @notice Block number that interest was last accrued at\n */\n uint256 public accrualBlockNumber;\n\n /**\n * @notice Accumulator of the total earned interest rate since the opening of the market\n */\n uint256 public borrowIndex;\n\n /**\n * @notice Total amount of outstanding borrows of the underlying in this market\n */\n uint256 public totalBorrows;\n\n /**\n * @notice Total amount of reserves of the underlying held in this market\n */\n uint256 public totalReserves;\n\n /**\n * @notice Total number of tokens in circulation\n */\n uint256 public totalSupply;\n\n /**\n * @notice Total bad debt of the market\n */\n uint256 public badDebt;\n\n // Official record of token balances for each account\n mapping(address => uint256) internal accountTokens;\n\n // Approved token transfer amounts on behalf of others\n mapping(address => mapping(address => uint256)) internal transferAllowances;\n\n // Mapping of account addresses to outstanding borrow balances\n mapping(address => BorrowSnapshot) internal accountBorrows;\n\n /**\n * @notice Share of seized collateral that is added to reserves\n */\n uint256 public protocolSeizeShareMantissa;\n\n /**\n * @notice Storage of Shortfall contract address\n */\n address public shortfall;\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[50] private __gap;\n}\n\n/**\n * @title VTokenInterface\n * @author Venus\n * @notice Interface implemented by the `VToken` contract\n */\nabstract contract VTokenInterface is VTokenStorage {\n struct RiskManagementInit {\n address shortfall;\n address payable protocolShareReserve;\n }\n\n /*** Market Events ***/\n\n /**\n * @notice Event emitted when interest is accrued\n */\n event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\n\n /**\n * @notice Event emitted when tokens are minted\n */\n event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\n\n /**\n * @notice Event emitted when tokens are redeemed\n */\n event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\n\n /**\n * @notice Event emitted when underlying is borrowed\n */\n event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\n\n /**\n * @notice Event emitted when a borrow is repaid\n */\n event RepayBorrow(\n address indexed payer,\n address indexed borrower,\n uint256 repayAmount,\n uint256 accountBorrows,\n uint256 totalBorrows\n );\n\n /**\n * @notice Event emitted when bad debt is accumulated on a market\n * @param borrower borrower to \"forgive\"\n * @param badDebtDelta amount of new bad debt recorded\n * @param badDebtOld previous bad debt value\n * @param badDebtNew new bad debt value\n */\n event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\n\n /**\n * @notice Event emitted when bad debt is recovered via an auction\n * @param badDebtOld previous bad debt value\n * @param badDebtNew new bad debt value\n */\n event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\n\n /**\n * @notice Event emitted when a borrow is liquidated\n */\n event LiquidateBorrow(\n address indexed liquidator,\n address indexed borrower,\n uint256 repayAmount,\n address indexed vTokenCollateral,\n uint256 seizeTokens\n );\n\n /*** Admin Events ***/\n\n /**\n * @notice Event emitted when comptroller is changed\n */\n event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\n\n /**\n * @notice Event emitted when shortfall contract address is changed\n */\n event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\n\n /**\n * @notice Event emitted when protocol share reserve contract address is changed\n */\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\n\n /**\n * @notice Event emitted when interestRateModel is changed\n */\n event NewMarketInterestRateModel(\n InterestRateModel indexed oldInterestRateModel,\n InterestRateModel indexed newInterestRateModel\n );\n\n /**\n * @notice Event emitted when protocol seize share is changed\n */\n event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\n\n /**\n * @notice Event emitted when the reserve factor is changed\n */\n event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\n\n /**\n * @notice Event emitted when the reserves are added\n */\n event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\n\n /**\n * @notice Event emitted when the reserves are reduced\n */\n event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);\n\n /**\n * @notice EIP20 Transfer event\n */\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /**\n * @notice EIP20 Approval event\n */\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Event emitted when healing the borrow\n */\n event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\n\n /**\n * @notice Event emitted when tokens are swept\n */\n event SweepToken(address indexed token);\n\n /*** User Interface ***/\n\n function mint(uint256 mintAmount) external virtual returns (uint256);\n\n function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\n\n function redeem(uint256 redeemTokens) external virtual returns (uint256);\n\n function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\n\n function borrow(uint256 borrowAmount) external virtual returns (uint256);\n\n function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\n\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\n\n function liquidateBorrow(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external virtual returns (uint256);\n\n function healBorrow(\n address payer,\n address borrower,\n uint256 repayAmount\n ) external virtual;\n\n function forceLiquidateBorrow(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral,\n bool skipCloseFactorCheck\n ) external virtual;\n\n function seize(\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external virtual;\n\n function transfer(address dst, uint256 amount) external virtual returns (bool);\n\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) external virtual returns (bool);\n\n function accrueInterest() external virtual returns (uint256);\n\n function sweepToken(IERC20Upgradeable token) external virtual;\n\n /*** Admin Functions ***/\n\n function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\n\n function reduceReserves(uint256 reduceAmount) external virtual;\n\n function exchangeRateCurrent() external virtual returns (uint256);\n\n function borrowBalanceCurrent(address account) external virtual returns (uint256);\n\n function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\n\n function addReserves(uint256 addAmount) external virtual;\n\n function totalBorrowsCurrent() external virtual returns (uint256);\n\n function balanceOfUnderlying(address owner) external virtual returns (uint256);\n\n function approve(address spender, uint256 amount) external virtual returns (bool);\n\n function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\n\n function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\n\n function allowance(address owner, address spender) external view virtual returns (uint256);\n\n function balanceOf(address owner) external view virtual returns (uint256);\n\n function getAccountSnapshot(address account)\n external\n view\n virtual\n returns (\n uint256,\n uint256,\n uint256,\n uint256\n );\n\n function borrowRatePerBlock() external view virtual returns (uint256);\n\n function supplyRatePerBlock() external view virtual returns (uint256);\n\n function borrowBalanceStored(address account) external view virtual returns (uint256);\n\n function exchangeRateStored() external view virtual returns (uint256);\n\n function getCash() external view virtual returns (uint256);\n\n /**\n * @notice Indicator that this is a VToken contract (for inspection)\n * @return Always true\n */\n function isVToken() external pure virtual returns (bool) {\n return true;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "yul": true + } + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} From 055cd32256604f3c52dc47185fb3ffc51e2eb616 Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Tue, 12 Sep 2023 17:46:59 +0000 Subject: [PATCH 35/39] chore(release): 2.0.1-dev.1 [skip ci] ## [2.0.1-dev.1](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0...v2.0.1-dev.1) (2023-09-12) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 756a6884b..63155b239 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [2.0.1-dev.1](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0...v2.0.1-dev.1) (2023-09-12) + ## [2.0.0](https://github.com/VenusProtocol/isolated-pools/compare/v1.3.0...v2.0.0) (2023-09-07) diff --git a/package.json b/package.json index 926d731ff..5e175c7da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "2.0.0", + "version": "2.0.1-dev.1", "description": "", "files": [ "artifacts", From 382d32d4164827f875a62332c47c9d3015a4db77 Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Tue, 12 Sep 2023 19:42:51 +0200 Subject: [PATCH 36/39] docs: update some values related with the shortfall handling --- README.md | 19 ++++++++++++++----- contracts/Shortfall/Shortfall.sol | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5fd4c66fd..59e1ad391 100644 --- a/README.md +++ b/README.md @@ -20,15 +20,24 @@ The Isolated Pools architecture centers around the `PoolRegistry` contract. The The risk fund concerns three main contracts: -- ProtocolShareReserve -- RiskFund -- ReserveHelpers +- `ProtocolShareReserve` +- `RiskFund` +- `ReserveHelpers` -The three contracts are designed to hold fees that have been accumulated from liquidations and spread, send a portion to the protocol treasury, and send the remainder to the RiskFund. When `reduceReserves()` is called in a `vToken` contract, all accumulated liquidation fees and spread are sent to the `ProtocolShareReserve` contract. Once funds are transferred to the `ProtocolShareReserve`, anyone can call `releaseFunds()` to transfer 70% to the `protocolIncome` address and the other 30% to the `riskFund` contract. Once in the `riskFund` contract, the tokens can be swapped via `PancakeSwap` pairs to the convertible base asset, which can be updated by the owner of the contract. When tokens are converted to the `convertibleBaseAsset`, they can be used in the `Shortfall` contract to auction off the pool's bad debt. Note that just as each pool is isolated, the risk funds for each pool are also isolated: only the risk fund for the same pool can be used when auctioning off the bad debt of the pool. +The three contracts are designed to hold funds that have been accumulated from interest reserves and liquidation incentives, send a portion to the protocol treasury, and send the remainder to the `RiskFund` contract. When `reduceReserves()` is called in a vToken contract, all accumulated liquidation fees and interests reservers are sent to the `ProtocolShareReserve` contract. Once funds are transferred to the `ProtocolShareReserve`, anyone can call `releaseFunds()` to transfer 50% to the `protocolIncome` address and the other 50% to the `riskFund` contract. Once in the `riskFund` contract, the tokens can be swapped via PancakeSwap pairs to the convertible base asset, which can be updated by the authorized accounts. When tokens are converted to the `convertibleBaseAsset`, they can be used in the `Shortfall` contract to auction off the pool's bad debt. Note that just as each pool is isolated, the risk funds for each pool are also isolated: only the risk fund for the same pool can be used when auctioning off the bad debt of the pool. ### Shortfall -`Shortfall` is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset` is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value. This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise, if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the risk fund in exchange for paying off all the pool's bad debt. +When a borrower's shortfall is detected in a market in the Isolated Pools, Venus halts the interest accrual, writes off the borrower's balance, and tracks the bad debt. + +`Shortfall` is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset` is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value (see `Shortfall.minimumPoolBadDebt()`). This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise, if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the risk fund in exchange for paying off all the pool's bad debt. + +The main configurable parameteres in the `Shortfall` contract (via VIP), and their initial values, are: + +- Minimum USD bad debt in the pool to allow the initiation of an auction. Initial value set to 1,000 USD +- Blocks to wait for first bidder. Initial value sets to 100 blocks +- Time to wait for next bidder. Initial value set to 100 blocks +- Incentive to auction participants. Initial value set to 1000 or 10% ### Rewards diff --git a/contracts/Shortfall/Shortfall.sol b/contracts/Shortfall/Shortfall.sol index 17c5747e6..6a609c08a 100644 --- a/contracts/Shortfall/Shortfall.sol +++ b/contracts/Shortfall/Shortfall.sol @@ -345,7 +345,7 @@ contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGua /** * @notice Update minimum pool bad debt to start auction - * @param _minimumPoolBadDebt Minimum bad debt in BUSD for a pool to start auction + * @param _minimumPoolBadDebt Minimum bad debt in the base asset for a pool to start auction * @custom:event Emits MinimumPoolBadDebtUpdated on success * @custom:access Restricted by ACM */ From 2914b4cd85839a0f22dd11a8f07aecc82a32304a Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Fri, 15 Sep 2023 06:34:11 +0000 Subject: [PATCH 37/39] chore(release): 2.1.0-dev.1 [skip ci] ## [2.1.0-dev.1](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.1-dev.1...v2.1.0-dev.1) (2023-09-15) ### Features * deploy PSR, RiskFund, Shortfall ([93408b1](https://github.com/VenusProtocol/isolated-pools/commit/93408b18da5a390869aab251354789910416c80e)) * set needed dependency to allow the deployment of SwapRouter ([96a684f](https://github.com/VenusProtocol/isolated-pools/commit/96a684fb80775b82a0ea02c2afc383fb032a7c09)) --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63155b239..8d87546cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [2.1.0-dev.1](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.1-dev.1...v2.1.0-dev.1) (2023-09-15) + + +### Features + +* deploy PSR, RiskFund, Shortfall ([93408b1](https://github.com/VenusProtocol/isolated-pools/commit/93408b18da5a390869aab251354789910416c80e)) +* set needed dependency to allow the deployment of SwapRouter ([96a684f](https://github.com/VenusProtocol/isolated-pools/commit/96a684fb80775b82a0ea02c2afc383fb032a7c09)) + ## [2.0.1-dev.1](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.0...v2.0.1-dev.1) (2023-09-12) ## [2.0.0](https://github.com/VenusProtocol/isolated-pools/compare/v1.3.0...v2.0.0) (2023-09-07) diff --git a/package.json b/package.json index ff9e7474a..d970425e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "2.0.1-dev.1", + "version": "2.1.0-dev.1", "description": "", "files": [ "artifacts", From 846bf3f2ec7610c63b520ce229b4f05f10697e77 Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Thu, 14 Sep 2023 13:25:45 +0200 Subject: [PATCH 38/39] docs: clarify some points about shortfalls --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 59e1ad391..2ae44fe6b 100644 --- a/README.md +++ b/README.md @@ -24,20 +24,20 @@ The risk fund concerns three main contracts: - `RiskFund` - `ReserveHelpers` -The three contracts are designed to hold funds that have been accumulated from interest reserves and liquidation incentives, send a portion to the protocol treasury, and send the remainder to the `RiskFund` contract. When `reduceReserves()` is called in a vToken contract, all accumulated liquidation fees and interests reservers are sent to the `ProtocolShareReserve` contract. Once funds are transferred to the `ProtocolShareReserve`, anyone can call `releaseFunds()` to transfer 50% to the `protocolIncome` address and the other 50% to the `riskFund` contract. Once in the `riskFund` contract, the tokens can be swapped via PancakeSwap pairs to the convertible base asset, which can be updated by the authorized accounts. When tokens are converted to the `convertibleBaseAsset`, they can be used in the `Shortfall` contract to auction off the pool's bad debt. Note that just as each pool is isolated, the risk funds for each pool are also isolated: only the risk fund for the same pool can be used when auctioning off the bad debt of the pool. +These three contracts are designed to hold funds that have been accumulated from interest reserves and liquidation incentives, send a portion to the protocol treasury, and send the remainder to the `RiskFund` contract. When `reduceReserves()` is called in a vToken contract, all accumulated liquidation fees and interests reserves are sent to the `ProtocolShareReserve` contract. Once funds are transferred to the `ProtocolShareReserve`, anyone can call `releaseFunds()` to transfer 50% to the `protocolIncome` address and the other 50% to the `riskFund` contract. Once in the `riskFund` contract, the tokens can be swapped via PancakeSwap pairs to the convertible base asset, which can be updated by the authorized accounts. When tokens are converted to the `convertibleBaseAsset`, they can be used in the `Shortfall` contract to auction off the pool's bad debt. Note that just as each pool is isolated, the risk funds for each pool are also isolated: only the associated risk fund for a pool can be used when auctioning off the bad debt of the pool. ### Shortfall -When a borrower's shortfall is detected in a market in the Isolated Pools, Venus halts the interest accrual, writes off the borrower's balance, and tracks the bad debt. +When a borrower's shortfall (total borrowed amount converted to USD is greater than the total supplied amount converted to USD) is detected in a market in the Isolated Pools, Venus halts the interest accrual, writes off the borrower's balance, and tracks the bad debt. -`Shortfall` is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset` is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value (see `Shortfall.minimumPoolBadDebt()`). This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner then exchanges for the entire risk fund. Otherwise, if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the risk fund in exchange for paying off all the pool's bad debt. +`Shortfall` is an auction contract designed to auction off the `convertibleBaseAsset` accumulated in `RiskFund`. The `convertibleBaseAsset` is auctioned in exchange for users paying off the pool's bad debt. An auction can be started by anyone once a pool's bad debt has reached a minimum value (see `Shortfall.minimumPoolBadDebt()`). This value is set and can be changed by the authorized accounts. If the pool’s bad debt exceeds the risk fund plus a 10% incentive, then the auction winner is determined by who will pay off the largest percentage of the pool's bad debt. The auction winner repays the bid percentage of the bad debt in exchange for the entire risk fund. Otherwise, if the risk fund covers the pool's bad debt plus the 10% incentive, then the auction winner is determined by who will take the smallest percentage of the risk fund in exchange for paying off all the pool's bad debt. -The main configurable parameteres in the `Shortfall` contract (via VIP), and their initial values, are: +The main configurable (via VIP) parameters in the `Shortfall` contract , and their initial values, are: -- Minimum USD bad debt in the pool to allow the initiation of an auction. Initial value set to 1,000 USD -- Blocks to wait for first bidder. Initial value sets to 100 blocks -- Time to wait for next bidder. Initial value set to 100 blocks -- Incentive to auction participants. Initial value set to 1000 or 10% +- `minimumPoolBadDebt` - Minimum USD bad debt in the pool to allow the initiation of an auction. Initial value set to 1,000 USD +- `waitForFirstBidder` - Blocks to wait for first bidder. Initial value sets to 100 blocks +- `nextBidderBlockLimit` - Time to wait for next bidder. Initial value set to 100 blocks +- `incentiveBps` - Incentive to auction participants. Initial value set to 1000 bps or 10% ### Rewards From 77bfaa659a4b3b0833795962712b8576dd28418c Mon Sep 17 00:00:00 2001 From: Venus Tools Date: Mon, 18 Sep 2023 16:31:15 +0000 Subject: [PATCH 39/39] chore(release): 2.1.0-dev.2 [skip ci] ## [2.1.0-dev.2](https://github.com/VenusProtocol/isolated-pools/compare/v2.1.0-dev.1...v2.1.0-dev.2) (2023-09-18) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d87546cf..0344a7aef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [2.1.0-dev.2](https://github.com/VenusProtocol/isolated-pools/compare/v2.1.0-dev.1...v2.1.0-dev.2) (2023-09-18) + ## [2.1.0-dev.1](https://github.com/VenusProtocol/isolated-pools/compare/v2.0.1-dev.1...v2.1.0-dev.1) (2023-09-15) diff --git a/package.json b/package.json index d970425e5..bff8edab0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@venusprotocol/isolated-pools", - "version": "2.1.0-dev.1", + "version": "2.1.0-dev.2", "description": "", "files": [ "artifacts",