Skip to content

Commit

Permalink
Merge pull request #278 from VenusProtocol/feat/VEN-1743
Browse files Browse the repository at this point in the history
[VEN-1743]: Refactor Risk Fund storage layout
  • Loading branch information
Debugger022 authored Jul 20, 2023
2 parents d9893fb + 72211a8 commit 25110cc
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 29 deletions.
4 changes: 3 additions & 1 deletion contracts/RiskFund/IRiskFund.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
35 changes: 25 additions & 10 deletions contracts/RiskFund/RiskFund.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}

Expand All @@ -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);

Expand All @@ -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).
Expand Down
2 changes: 1 addition & 1 deletion contracts/Shortfall/Shortfall.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
24 changes: 12 additions & 12 deletions tests/hardhat/Fork/RiskFund.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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);
Expand All @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion tests/hardhat/Fork/RiskFundSwap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down
10 changes: 6 additions & 4 deletions tests/hardhat/Shortfall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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));

Expand Down

0 comments on commit 25110cc

Please sign in to comment.