diff --git a/contracts/RiskFund/IRiskFund.sol b/contracts/RiskFund/IRiskFund.sol index 3c5bc980f..e5cc161f4 100644 --- a/contracts/RiskFund/IRiskFund.sol +++ b/contracts/RiskFund/IRiskFund.sol @@ -17,5 +17,7 @@ interface IRiskFund { function updateAssetsState(address comptroller, address asset) external; - function poolReserves(address comptroller) external view returns (uint256); + function convertibleBaseAsset() external view returns (address); + + function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256); } diff --git a/contracts/RiskFund/RiskFund.sol b/contracts/RiskFund/RiskFund.sol index bbcfd07a9..06bdd5a4b 100644 --- a/contracts/RiskFund/RiskFund.sol +++ b/contracts/RiskFund/RiskFund.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.13; import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import { SafeERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import { AccessControlledV8 } from "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol"; - +import { ComptrollerInterface } from "../ComptrollerInterface.sol"; import { IRiskFund } from "./IRiskFund.sol"; import { ReserveHelpers } from "./ReserveHelpers.sol"; import { ExponentialNoError } from "../ExponentialNoError.sol"; @@ -25,14 +25,10 @@ import { ensureNonzeroAddress } from "../lib/validators.sol"; */ contract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, MaxLoopsLimitHelper, IRiskFund { using SafeERC20Upgradeable for IERC20Upgradeable; - + address public convertibleBaseAsset; + address public shortfall; address private pancakeSwapRouter; uint256 private minAmountToConvert; - address private convertibleBaseAsset; - address private shortfall; - - // Store base asset's reserve for specific pool - mapping(address => uint256) public poolReserves; /// @notice Emitted when pool registry address is updated event PoolRegistryUpdated(address indexed oldPoolRegistry, address indexed newPoolRegistry); @@ -177,7 +173,8 @@ contract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, Max require(Comptroller(comptroller).isMarketListed(vToken), "market is not listed"); uint256 swappedTokens = _swapAsset(vToken, comptroller, amountsOutMin[i], paths[i]); - poolReserves[comptroller] = poolReserves[comptroller] + swappedTokens; + poolsAssetsReserves[comptroller][convertibleBaseAsset] += swappedTokens; + assetsReserves[convertibleBaseAsset] += swappedTokens; totalAmount = totalAmount + swappedTokens; } @@ -195,9 +192,17 @@ contract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, Max function transferReserveForAuction(address comptroller, uint256 amount) external override returns (uint256) { address shortfall_ = shortfall; require(msg.sender == shortfall_, "Risk fund: Only callable by Shortfall contract"); - require(amount <= poolReserves[comptroller], "Risk Fund: Insufficient pool reserve."); + require( + amount <= poolsAssetsReserves[comptroller][convertibleBaseAsset], + "Risk Fund: Insufficient pool reserve." + ); + unchecked { + poolsAssetsReserves[comptroller][convertibleBaseAsset] = + poolsAssetsReserves[comptroller][convertibleBaseAsset] - + amount; + } unchecked { - poolReserves[comptroller] = poolReserves[comptroller] - amount; + assetsReserves[convertibleBaseAsset] = assetsReserves[convertibleBaseAsset] - amount; } IERC20Upgradeable(convertibleBaseAsset).safeTransfer(shortfall_, amount); @@ -214,6 +219,16 @@ contract RiskFund is AccessControlledV8, ExponentialNoError, ReserveHelpers, Max _setMaxLoopsLimit(limit); } + /** + * @notice Get the Amount of the Base asset in the risk fund for the specific pool. + * @param comptroller Comptroller address(pool). + * @return Base Asset's reserve in risk fund. + */ + function getPoolsBaseAssetReserves(address comptroller) external view returns (uint256) { + require(ComptrollerInterface(comptroller).isComptroller(), "Risk Fund: Comptroller address invalid"); + return poolsAssetsReserves[comptroller][convertibleBaseAsset]; + } + /** * @notice Update the reserve of the asset for the specific pool after transferring to risk fund. * @param comptroller Comptroller address(pool). diff --git a/contracts/Shortfall/Shortfall.sol b/contracts/Shortfall/Shortfall.sol index 64717d070..b0edfa090 100644 --- a/contracts/Shortfall/Shortfall.sol +++ b/contracts/Shortfall/Shortfall.sol @@ -463,7 +463,7 @@ contract Shortfall is Ownable2StepUpgradeable, AccessControlledV8, ReentrancyGua require(poolBadDebt >= minimumPoolBadDebt, "pool bad debt is too low"); - uint256 riskFundBalance = riskFund.poolReserves(comptroller); + uint256 riskFundBalance = riskFund.getPoolsBaseAssetReserves(comptroller); uint256 remainingRiskFundBalance = riskFundBalance; uint256 incentivizedRiskFundBalance = poolBadDebt + ((poolBadDebt * incentiveBps) / MAX_BPS); if (incentivizedRiskFundBalance >= riskFundBalance) { diff --git a/tests/hardhat/Fork/RiskFund.ts b/tests/hardhat/Fork/RiskFund.ts index 4dc92cf97..90a3dad8a 100644 --- a/tests/hardhat/Fork/RiskFund.ts +++ b/tests/hardhat/Fork/RiskFund.ts @@ -659,7 +659,7 @@ describe("Risk Fund: Tests", function () { ], ); - expect(await riskFund.poolReserves(comptroller1Proxy.address)).to.be.equal("29916047622748892393"); + expect(await riskFund.getPoolsBaseAssetReserves(comptroller1Proxy.address)).to.be.equal("29916047622748892393"); const balanceAfter = await USDC.balanceOf(riskFund.address); expect(balanceAfter).equal("0"); @@ -712,15 +712,13 @@ describe("Risk Fund: Tests", function () { ], ); - expect(await riskFund.poolReserves(comptroller1Proxy.address)).to.be.equal("59832095245497784786"); + expect(await riskFund.getPoolsBaseAssetReserves(comptroller1Proxy.address)).to.be.equal("59832095245497784786"); const balanceBUSD = await BUSD.balanceOf(riskFund.address); expect(Number(balanceBUSD)).to.be.closeTo(Number(convertToUnit(60, 18)), Number(convertToUnit(3, 17))); - const pool1Reserve = await riskFund.poolReserves(comptroller1Proxy.address); - const pool2Reserve = await riskFund.poolReserves("0x0000000000000000000000000000000000000000"); + const pool1Reserve = await riskFund.getPoolsBaseAssetReserves(comptroller1Proxy.address); expect(Number(pool1Reserve)).to.be.closeTo(Number(convertToUnit(60, 18)), Number(convertToUnit(3, 17))); - expect(pool2Reserve).equal(0); }); }); // myContract.connect(myFake.wallet).doSomething(); @@ -783,7 +781,7 @@ describe("Risk Fund: Tests", function () { .transferReserveForAuction(comptroller1Proxy.address, convertToUnit(20, 18)); const afterTransfer = await BUSD.balanceOf(shortfall.address); const remainingBalance = await BUSD.balanceOf(riskFund.address); - const poolReserve = await riskFund.poolReserves(comptroller1Proxy.address); + const poolReserve = await riskFund.getPoolsBaseAssetReserves(comptroller1Proxy.address); const amount = Number(afterTransfer) - Number(beforeTransfer); expect(amount).to.be.closeTo(Number(convertToUnit(20, 18)), Number(convertToUnit(3, 17))); @@ -824,7 +822,7 @@ describe("Risk Fund: Tests", function () { ], ); - expect(await riskFund.poolReserves(comptroller1Proxy.address)).to.be.equal(0); + expect(await riskFund.getPoolsBaseAssetReserves(comptroller1Proxy.address)).to.be.equal(0); // revoke await accessControlManager.revokeCallPermission( @@ -956,7 +954,7 @@ describe("Risk Fund: Tests", function () { ], ); - expect(await riskFund.poolReserves(comptroller1Proxy.address)).to.be.equal("56841295980235012443"); + expect(await riskFund.getPoolsBaseAssetReserves(comptroller1Proxy.address)).to.be.equal("56841295980235012443"); riskUSDTFor1 = await riskFund.getPoolAssetReserve(comptroller1Proxy.address, USDT.address); riskUSDCFor1 = await riskFund.getPoolAssetReserve(comptroller1Proxy.address, USDC.address); @@ -970,13 +968,15 @@ describe("Risk Fund: Tests", function () { expect(riskUSDTFor2).equal(0); expect(riskUSDCFor2).equal(0); expect(riskUSDTFor3).equal(0); - expect(riskBUSDTFor3).equal(0); - const poolReserve1 = await riskFund.poolReserves(comptroller1Proxy.address); + // As BUSD is base asset so PoolAssetReserves should be present. + expect(riskBUSDTFor3).to.be.closeTo(convertToUnit(53, 18), convertToUnit(9, 17)); - const poolReserve2 = await riskFund.poolReserves(comptroller2Proxy.address); + const poolReserve1 = await riskFund.getPoolsBaseAssetReserves(comptroller1Proxy.address); - const poolReserve3 = await riskFund.poolReserves(comptroller3Proxy.address); + const poolReserve2 = await riskFund.getPoolsBaseAssetReserves(comptroller2Proxy.address); + + const poolReserve3 = await riskFund.getPoolsBaseAssetReserves(comptroller3Proxy.address); expect(poolReserve1).to.be.closeTo(convertToUnit(56, 18), convertToUnit(9, 17)); expect(poolReserve2).to.be.closeTo(convertToUnit(56, 18), convertToUnit(9, 17)); diff --git a/tests/hardhat/Fork/RiskFundSwap.ts b/tests/hardhat/Fork/RiskFundSwap.ts index 529a43d92..8061a5b3a 100644 --- a/tests/hardhat/Fork/RiskFundSwap.ts +++ b/tests/hardhat/Fork/RiskFundSwap.ts @@ -231,7 +231,7 @@ describe("Risk Fund: Swap Tests", () => { await protocolShareReserve.releaseFunds(comptroller1Proxy.address, USDT.address, REDUCE_RESERVE_AMOUNT); await riskFund.swapPoolsAssets([vUSDT.address], [parseUnits("10", 18)], [[USDT.address, BUSD.address]]); - expect(await riskFund.poolReserves(comptroller1Proxy.address)).to.be.equal("14960261570862459704"); + expect(await riskFund.getPoolsBaseAssetReserves(comptroller1Proxy.address)).to.be.equal("14960261570862459704"); const balance = await BUSD.balanceOf(riskFund.address); expect(Number(balance)).to.be.closeTo(Number(parseUnits("15", 18)), Number(parseUnits("1", 17))); diff --git a/tests/hardhat/Shortfall.ts b/tests/hardhat/Shortfall.ts index 94aa6dbde..9bd1792e4 100644 --- a/tests/hardhat/Shortfall.ts +++ b/tests/hardhat/Shortfall.ts @@ -139,7 +139,7 @@ async function shortfallFixture() { comptroller.oracle.returns(fakePriceOracle.address); - fakeRiskFund.poolReserves.returns(parseUnits(riskFundBalance, 18)); + fakeRiskFund.getPoolsBaseAssetReserves.returns(parseUnits(riskFundBalance, 18)); fakeRiskFund.transferReserveForAuction.returns(0); // Access Control @@ -331,7 +331,9 @@ 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 fakeRiskFund.getPoolsBaseAssetReserves(comptroller.address)).equal( + parseUnits(riskFundBalance, 18).toString(), + ); expect(await vDAI.badDebt()).equal(parseUnits("1000", 18)); expect(await vWBTC.badDebt()).equal(parseUnits("1", 8)); @@ -504,7 +506,7 @@ describe("Shortfall: Tests", async function () { await vWBTC.setVariable("badDebt", parseUnits("1", 8)); riskFundBalance = "50000"; - fakeRiskFund.poolReserves.returns(parseUnits(riskFundBalance, 18)); + fakeRiskFund.getPoolsBaseAssetReserves.returns(parseUnits(riskFundBalance, 18)); const receipt = await shortfall.startAuction(poolAddress); startBlockNumber = receipt.blockNumber; @@ -737,7 +739,7 @@ describe("Shortfall: Deflationary token Scenario", async function () { await vFloki.setVariable("badDebt", parseUnits("100", 18)); riskFundBalance = "500"; - fakeRiskFund.poolReserves.returns(parseUnits(riskFundBalance, 18)); + fakeRiskFund.getPoolsBaseAssetReserves.returns(parseUnits(riskFundBalance, 18)); await shortfall.connect(owner).updateMinimumPoolBadDebt(convertToUnit(10, 18));