Skip to content

Commit

Permalink
Merge pull request #207 from VenusProtocol/feature/VEN-1151-VEN-1152
Browse files Browse the repository at this point in the history
[VEN-1151][VEN-1152][VEN-2046] send reserves to PSR  and remove PSR contracts
  • Loading branch information
GitGuru7 authored Oct 31, 2023
2 parents 02b305c + b139a9f commit d2e36ac
Show file tree
Hide file tree
Showing 22 changed files with 1,633 additions and 554 deletions.
11 changes: 0 additions & 11 deletions contracts/RiskFund/IProtocolShareReserve.sol

This file was deleted.

109 changes: 0 additions & 109 deletions contracts/RiskFund/ProtocolShareReserve.sol

This file was deleted.

63 changes: 51 additions & 12 deletions contracts/VToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { Ownable2StepUpgradeable } from "@openzeppelin/contracts-upgradeable/acc
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 { IProtocolShareReserve } from "@venusprotocol/protocol-reserve/contracts/Interfaces/IProtocolShareReserve.sol";

import { VTokenInterface } from "./VTokenInterfaces.sol";
import { ComptrollerInterface, ComptrollerViewInterface } from "./ComptrollerInterface.sol";
import { TokenErrorReporter } from "./ErrorReporter.sol";
import { InterestRateModel } from "./InterestRateModel.sol";
import { ExponentialNoError } from "./ExponentialNoError.sol";
import { IProtocolShareReserve } from "./RiskFund/IProtocolShareReserve.sol";
import { ensureNonzeroAddress } from "./lib/validators.sol";

/**
Expand Down Expand Up @@ -51,7 +51,9 @@ contract VToken is

uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%

/*** Reentrancy Guard ***/
/**
* Reentrancy Guard **
*/

/**
* @dev Prevents a contract from calling itself, directly or indirectly.
Expand Down Expand Up @@ -413,6 +415,7 @@ contract VToken is

/**
* @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract
* @dev Gracefully return if reserves already reduced in accrueInterest
* @param reduceAmount Amount of reduction to reserves
* @custom:event Emits ReservesReduced event; may emit AccrueInterest
* @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash
Expand All @@ -421,6 +424,7 @@ contract VToken is
*/
function reduceReserves(uint256 reduceAmount) external override nonReentrant {
accrueInterest();
if (reduceReservesBlockNumber == _getBlockNumber()) return;
_reduceReservesFresh(reduceAmount);
}

Expand Down Expand Up @@ -609,6 +613,18 @@ contract VToken is
emit SweepToken(address(token));
}

/**
* @notice A public function to set new threshold of block difference after which funds will be sent to the protocol share reserve
* @param _newReduceReservesBlockDelta block difference value
* @custom:access Only Governance
*/
function setReduceReservesBlockDelta(uint256 _newReduceReservesBlockDelta) external {
_checkAccessAllowed("setReduceReservesBlockDelta(uint256)");
require(_newReduceReservesBlockDelta > 0, "Invalid Input");
emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, _newReduceReservesBlockDelta);
reduceReservesBlockDelta = _newReduceReservesBlockDelta;
}

/**
* @notice Get the current allowance from `owner` for `spender`
* @param owner The address of the account which owns the tokens to be spent
Expand Down Expand Up @@ -709,7 +725,9 @@ contract VToken is
/**
* @notice Applies accrued interest to total borrows and reserves
* @dev This calculates interest accrued from the last checkpointed block
* up to the current block and writes new checkpoint to storage.
* up to the current block and writes new checkpoint to storage and
* reduce spread reserves to protocol share reserve
* if currentBlock - reduceReservesBlockNumber >= blockDelta
* @return Always NO_ERROR
* @custom:event Emits AccrueInterest event on success
* @custom:access Not restricted
Expand Down Expand Up @@ -766,6 +784,11 @@ contract VToken is
totalBorrows = totalBorrowsNew;
totalReserves = totalReservesNew;

if (currentBlockNumber - reduceReservesBlockNumber >= reduceReservesBlockDelta) {
reduceReservesBlockNumber = currentBlockNumber;
_reduceReservesFresh(totalReservesNew);
}

/* We emit an AccrueInterest event */
emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);

Expand Down Expand Up @@ -1146,22 +1169,30 @@ contract VToken is
uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;
Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });
uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);
uint256 totalReservesNew = totalReserves + protocolSeizeAmount;

/////////////////////////
// EFFECTS & INTERACTIONS
// (No safe failures beyond this point)

/* We write the calculated values into storage */
totalReserves = totalReservesNew;
totalSupply = totalSupply - protocolSeizeTokens;
accountTokens[borrower] = accountTokens[borrower] - seizeTokens;
accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;

// _doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.
// Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.
_doTransferOut(protocolShareReserve, protocolSeizeAmount);

// Update the pool asset's state in the protocol share reserve for the above transfer.
IProtocolShareReserve(protocolShareReserve).updateAssetsState(
address(comptroller),
underlying,
IProtocolShareReserve.IncomeType.LIQUIDATION
);

/* Emit a Transfer event */
emit Transfer(borrower, liquidator, liquidatorSeizeTokens);
emit Transfer(borrower, address(this), protocolSeizeTokens);
emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);
emit ProtocolSeize(borrower, protocolShareReserve, protocolSeizeAmount);
}

function _setComptroller(ComptrollerInterface newComptroller) internal {
Expand Down Expand Up @@ -1228,6 +1259,9 @@ contract VToken is
* @param reduceAmount Amount of reduction to reserves
*/
function _reduceReservesFresh(uint256 reduceAmount) internal {
if (reduceAmount == 0) {
return;
}
// totalReserves - reduceAmount
uint256 totalReservesNew;

Expand Down Expand Up @@ -1260,9 +1294,13 @@ contract VToken is
_doTransferOut(protocolShareReserve, reduceAmount);

// Update the pool asset's state in the protocol share reserve for the above transfer.
IProtocolShareReserve(protocolShareReserve).updateAssetsState(address(comptroller), underlying);
IProtocolShareReserve(protocolShareReserve).updateAssetsState(
address(comptroller),
underlying,
IProtocolShareReserve.IncomeType.SPREAD
);

emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);
emit SpreadReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);
}

/**
Expand Down Expand Up @@ -1292,7 +1330,9 @@ contract VToken is
emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);
}

/*** Safe Token ***/
/**
* Safe Token **
*/

/**
* @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.
Expand Down Expand Up @@ -1448,8 +1488,7 @@ contract VToken is
* @return The quantity of underlying tokens owned by this contract
*/
function _getCashPrior() internal view virtual returns (uint256) {
IERC20Upgradeable token = IERC20Upgradeable(underlying);
return token.balanceOf(address(this));
return IERC20Upgradeable(underlying).balanceOf(address(this));
}

/**
Expand Down
26 changes: 23 additions & 3 deletions contracts/VTokenInterfaces.sol
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,22 @@ contract VTokenStorage {
*/
address public shortfall;

/**
* @notice delta block after which reserves will be reduced
*/
uint256 public reduceReservesBlockDelta;

/**
* @notice last block number at which reserves were reduced
*/
uint256 public reduceReservesBlockNumber;

/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
uint256[48] private __gap;
}

/**
Expand Down Expand Up @@ -247,9 +257,9 @@ abstract contract VTokenInterface is VTokenStorage {
event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);

/**
* @notice Event emitted when the reserves are reduced
* @notice Event emitted when the spread reserves are reduced
*/
event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves);
event SpreadReservesReduced(address indexed protocolShareReserve, uint256 reduceAmount, uint256 newTotalReserves);

/**
* @notice EIP20 Transfer event
Expand All @@ -271,6 +281,16 @@ abstract contract VTokenInterface is VTokenStorage {
*/
event SweepToken(address indexed token);

/**
* @notice Event emitted when reduce reserves block delta is changed
*/
event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);

/**
* @notice Event emitted when liquidation reserves are reduced
*/
event ProtocolSeize(address indexed from, address indexed to, uint256 amount);

/*** User Interface ***/

function mint(uint256 mintAmount) external virtual returns (uint256);
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/Mocks/MockPriceOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.10;
import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol";
import { BinanceOracle } from "@venusprotocol/oracle/contracts/oracles/BinanceOracle.sol";
import { ChainlinkOracle } from "@venusprotocol/oracle/contracts/oracles/ChainlinkOracle.sol";

import { ProtocolShareReserve } from "@venusprotocol/protocol-reserve/contracts/ProtocolReserve/ProtocolShareReserve.sol";
import { VToken } from "../../VToken.sol";

contract MockPriceOracle is ResilientOracleInterface {
Expand Down
4 changes: 2 additions & 2 deletions contracts/test/VTokenHarness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ contract VTokenHarness is VToken {
_liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);
}

function harnessReduceReservesFresh(uint256 amount) external {
return _reduceReservesFresh(amount);
function harnessReduceReservesFresh(uint256 spreadAmount) external {
return _reduceReservesFresh(spreadAmount);
}

function harnessSetReserveFactorFresh(uint256 newReserveFactorMantissa) external {
Expand Down
16 changes: 16 additions & 0 deletions deploy/013-vip-based-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,21 @@ const addMarket = async (
};
};

const setReduceReservesBlockDelta = async (
vTokenAddress: string,
vTokenConfig: VTokenConfig,
): Promise<GovernanceCommand> => {
const { name, reduceReservesBlockDelta } = vTokenConfig;
console.log("Adding a command to set reduce reserves blcok delta to " + name);
return {
contract: vTokenAddress,
signature: "setReduceReservesBlockDelta(uint256)",
argTypes: ["uint256"],
parameters: [reduceReservesBlockDelta],
value: 0,
};
};

const addMarkets = async (
unregisteredVTokens: PoolConfig[],
deploymentConfig: DeploymentConfig,
Expand All @@ -276,6 +291,7 @@ const addMarkets = async (
return [
...(await transferInitialLiquidity(vTokenConfig, deploymentConfig, hre)),
...(await approvePoolRegistry(poolRegistry, vTokenConfig, deploymentConfig)),
await setReduceReservesBlockDelta(vToken.address, vTokenConfig),
await addMarket(poolRegistry, vToken.address, vTokenConfig, hre),
];
}),
Expand Down
Loading

0 comments on commit d2e36ac

Please sign in to comment.