Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New main release #272

Merged
merged 37 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4b2ada4
feat: stop rewards at a block number
web3rover Jun 26, 2023
13bdc7f
feat: set/update last rewarding block
web3rover Jun 26, 2023
84a8a62
fix: bump hardhat deploy
coreyar Jun 26, 2023
4d8720f
feat: added tests for pausing rewards
web3rover Jun 27, 2023
1b173dc
fix: fixed tests
web3rover Jun 28, 2023
05d431b
Merge pull request #269 from VenusProtocol/main
coreyar Jul 4, 2023
12cade7
Merge pull request #260 from VenusProtocol/bump-hadhat-deploy
coreyar Jul 5, 2023
f546394
chore(release): 1.1.1-dev.1 [skip ci]
toolsvenus Jul 5, 2023
2e0f01d
chore: fixed typo
web3rover Jul 7, 2023
c459065
fix: VEN-1684 and VEN-1685
web3rover Jul 7, 2023
9b0566b
fix: pause rewards in pool lens
web3rover Jul 7, 2023
b6413c5
fix: VENUS-RD-001
web3rover Jul 7, 2023
1c1f749
fix: VENUS-RD-002
web3rover Jul 7, 2023
07fd8f3
fix: VENUS-RD-003
web3rover Jul 7, 2023
a61b4c5
chore: fixed lint
web3rover Jul 7, 2023
97d704e
fix: use node 18
coreyar Jul 7, 2023
e32ef5d
fix: shorten the size of revert string
web3rover Jul 10, 2023
71a36e6
fix: use getBlockNumber()
web3rover Jul 10, 2023
f308a8c
Merge pull request #257 from VenusProtocol/feat/stop-rewards
web3rover Jul 10, 2023
a5c01e7
fix: use hardhat 2.16.1
coreyar Jul 7, 2023
17111a3
chore(release): 1.2.0-dev.1 [skip ci]
toolsvenus Jul 10, 2023
4187ec5
Merge pull request #271 from VenusProtocol/ven-1689-fix-hardhat-compi…
coreyar Jul 10, 2023
21bc6f4
chore(release): 1.2.0-dev.2 [skip ci]
toolsvenus Jul 10, 2023
1ce01d7
docs: add Certik audit on RewardsDistributor contract
chechu Jul 11, 2023
334110b
chore: faucet correct amounts for duplicate tokens
kkirka Jul 7, 2023
0587f16
chore: remove no-op commands from VIPs
kkirka Jul 7, 2023
a6cd456
feat: add reward configs
kkirka Jul 7, 2023
73970e2
chore: avoid redeploying mocks
kkirka Jul 11, 2023
ac37481
chore: use a single implementation for all rewards distributors
kkirka Jul 11, 2023
3a3a8a2
feat: add mainnet deployments for rewards distributors
kkirka Jul 11, 2023
5cf6ea3
feat: add testnet deployment for rewards distributors
kkirka Jul 11, 2023
feaeddf
feat: redeploy PoolLens on mainnet
kkirka Jul 11, 2023
ea5c204
feat: redeploy PoolLens on testnet
kkirka Jul 11, 2023
17aadc1
Merge pull request #274 from VenusProtocol/docs/certik-audit
chechu Jul 12, 2023
0686249
chore(release): 1.2.0-dev.3 [skip ci]
toolsvenus Jul 12, 2023
dabce71
Merge pull request #273 from VenusProtocol/feat/deploy-rewards
kkirka Jul 12, 2023
95b1c89
chore(release): 1.2.0-dev.4 [skip ci]
toolsvenus Jul 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup Node.js environment
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: "yarn"

- name: Install dependencies
Expand All @@ -36,7 +36,7 @@ jobs:

- uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: "yarn"

- name: Install deps
Expand Down Expand Up @@ -77,12 +77,15 @@ jobs:
- name: Setup Node.js environment
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: "yarn"

- name: Install dependencies
# Hack to get around failing "ethereumjs-abi The remote archive doesn't match the expected checksum" error
run: YARN_CHECKSUM_BEHAVIOR=update yarn

- name: Build
run: yarn build

- name: Verify deployments work
run: yarn hardhat deploy
49 changes: 49 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,52 @@
## [1.2.0-dev.4](https://github.com/VenusProtocol/isolated-pools/compare/v1.2.0-dev.3...v1.2.0-dev.4) (2023-07-12)


### Features

* add mainnet deployments for rewards distributors ([3a3a8a2](https://github.com/VenusProtocol/isolated-pools/commit/3a3a8a28a6563117604980fea689b5e3203fea85))
* add reward configs ([a6cd456](https://github.com/VenusProtocol/isolated-pools/commit/a6cd456cd84de28d0adc2c69637c74a29cb5224f))
* add testnet deployment for rewards distributors ([5cf6ea3](https://github.com/VenusProtocol/isolated-pools/commit/5cf6ea34496c1f17be196a40706cf0da64b8dd38))
* redeploy PoolLens on mainnet ([feaeddf](https://github.com/VenusProtocol/isolated-pools/commit/feaeddf0b9a28c876cb4ca81b6129bbd69e4e348))
* redeploy PoolLens on testnet ([ea5c204](https://github.com/VenusProtocol/isolated-pools/commit/ea5c20422274d6137591344c5259593ad99e4dd4))

## [1.2.0-dev.3](https://github.com/VenusProtocol/isolated-pools/compare/v1.2.0-dev.2...v1.2.0-dev.3) (2023-07-12)

## [1.2.0-dev.2](https://github.com/VenusProtocol/isolated-pools/compare/v1.2.0-dev.1...v1.2.0-dev.2) (2023-07-10)


### Bug Fixes

* use hardhat 2.16.1 ([a5c01e7](https://github.com/VenusProtocol/isolated-pools/commit/a5c01e7d452d04b10dba7466be9e7d25f43cf01b))
* use node 18 ([97d704e](https://github.com/VenusProtocol/isolated-pools/commit/97d704e0042a3d535d6605a8791541f2b671cdf3))

## [1.2.0-dev.1](https://github.com/VenusProtocol/isolated-pools/compare/v1.1.1-dev.1...v1.2.0-dev.1) (2023-07-10)


### Features

* added tests for pausing rewards ([4d8720f](https://github.com/VenusProtocol/isolated-pools/commit/4d8720f483bc76d7c1f39d69a6a2ff32118111d3))
* set/update last rewarding block ([13bdc7f](https://github.com/VenusProtocol/isolated-pools/commit/13bdc7f862929f8cc350f47e0ba922cd2edfe65f))
* stop rewards at a block number ([4b2ada4](https://github.com/VenusProtocol/isolated-pools/commit/4b2ada43e7de8375062036d3be7e71f4dd672fdd))


### Bug Fixes

* fixed tests ([1b173dc](https://github.com/VenusProtocol/isolated-pools/commit/1b173dc1b0a7232a02c174559535ae18c3801b9e))
* pause rewards in pool lens ([9b0566b](https://github.com/VenusProtocol/isolated-pools/commit/9b0566b24a06fe22180a3752eea0ac8c127eb4d7))
* shorten the size of revert string ([e32ef5d](https://github.com/VenusProtocol/isolated-pools/commit/e32ef5dd249db156821b21984b46fd4c507de51e))
* use getBlockNumber() ([71a36e6](https://github.com/VenusProtocol/isolated-pools/commit/71a36e64cf1f32d81ba9bd728f230fe488b9190b))
* VEN-1684 and VEN-1685 ([c459065](https://github.com/VenusProtocol/isolated-pools/commit/c4590657669993c901e64a5fe9837faeef5017d0))
* VENUS-RD-001 ([b6413c5](https://github.com/VenusProtocol/isolated-pools/commit/b6413c5908e3b62a14b038bc78486f2a765d085a))
* VENUS-RD-002 ([1c1f749](https://github.com/VenusProtocol/isolated-pools/commit/1c1f7498d144702f61ec37f27011f60f1b955216))
* VENUS-RD-003 ([07fd8f3](https://github.com/VenusProtocol/isolated-pools/commit/07fd8f3af742b7fa04f201f6024291ca46ba6a71))

## [1.1.1-dev.1](https://github.com/VenusProtocol/isolated-pools/compare/v1.1.0...v1.1.1-dev.1) (2023-07-05)


### Bug Fixes

* bump hardhat deploy ([84a8a62](https://github.com/VenusProtocol/isolated-pools/commit/84a8a62ee3d289562f82109486dcbac0492552bd))

## [1.1.0](https://github.com/VenusProtocol/isolated-pools/compare/v1.0.0...v1.1.0) (2023-07-04)


Expand Down
Binary file added audits/051_rewardsDistributor_certik_20230610.pdf
Binary file not shown.
18 changes: 16 additions & 2 deletions contracts/Lens/PoolLens.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ contract PoolLens is ExponentialNoError {
uint224 index;
// The block number the index was last updated at
uint32 block;
// The block number at which to stop rewards
uint32 lastRewardingBlock;
}

/**
Expand Down Expand Up @@ -444,9 +446,11 @@ contract PoolLens is ExponentialNoError {
for (uint256 i; i < markets.length; ++i) {
// Market borrow and supply state we will modify update in-memory, in order to not modify storage
RewardTokenState memory borrowState;
(borrowState.index, borrowState.block) = rewardsDistributor.rewardTokenBorrowState(address(markets[i]));
(borrowState.index, borrowState.block, borrowState.lastRewardingBlock) = rewardsDistributor
.rewardTokenBorrowState(address(markets[i]));
RewardTokenState memory supplyState;
(supplyState.index, supplyState.block) = rewardsDistributor.rewardTokenSupplyState(address(markets[i]));
(supplyState.index, supplyState.block, supplyState.lastRewardingBlock) = rewardsDistributor
.rewardTokenSupplyState(address(markets[i]));
Exp memory marketBorrowIndex = Exp({ mantissa: markets[i].borrowIndex() });

// Update market supply and borrow index in-memory
Expand Down Expand Up @@ -484,6 +488,11 @@ contract PoolLens is ExponentialNoError {
) internal view {
uint256 borrowSpeed = rewardsDistributor.rewardTokenBorrowSpeeds(vToken);
uint256 blockNumber = block.number;

if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {
blockNumber = borrowState.lastRewardingBlock;
}

uint256 deltaBlocks = sub_(blockNumber, uint256(borrowState.block));
if (deltaBlocks > 0 && borrowSpeed > 0) {
// Remove the total earned interest rate since the opening of the market from total borrows
Expand All @@ -505,6 +514,11 @@ contract PoolLens is ExponentialNoError {
) internal view {
uint256 supplySpeed = rewardsDistributor.rewardTokenSupplySpeeds(vToken);
uint256 blockNumber = block.number;

if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {
blockNumber = supplyState.lastRewardingBlock;
}

uint256 deltaBlocks = sub_(blockNumber, uint256(supplyState.block));
if (deltaBlocks > 0 && supplySpeed > 0) {
uint256 supplyTokens = VToken(vToken).totalSupply();
Expand Down
91 changes: 87 additions & 4 deletions contracts/Rewards/RewardsDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ contract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, Acce
uint224 index;
// The block number the index was last updated at
uint32 block;
// The block number at which to stop rewards
uint32 lastRewardingBlock;
}

/// @notice The initial REWARD TOKEN index for a market
Expand Down Expand Up @@ -112,6 +114,12 @@ contract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, Acce
/// @notice Emitted when a reward for contributor is updated
event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);

/// @notice Emitted when a reward token last rewarding block for supply is updated
event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);

/// @notice Emitted when a reward token last rewarding block for borrow is updated
event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);

modifier onlyComptroller() {
require(address(comptroller) == msg.sender, "Only comptroller can call this function");
_;
Expand Down Expand Up @@ -224,16 +232,39 @@ contract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, Acce
) external {
_checkAccessAllowed("setRewardTokenSpeeds(address[],uint256[],uint256[])");
uint256 numTokens = vTokens.length;
require(
numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length,
"RewardsDistributor::setRewardTokenSpeeds invalid input"
);
require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, "invalid setRewardTokenSpeeds");

for (uint256 i; i < numTokens; ++i) {
_setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);
}
}

/**
* @notice Set REWARD TOKEN last rewarding block for the specified markets
* @param vTokens The markets whose REWARD TOKEN last rewarding block to update
* @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market
* @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market
*/
function setLastRewardingBlocks(
VToken[] calldata vTokens,
uint32[] calldata supplyLastRewardingBlocks,
uint32[] calldata borrowLastRewardingBlocks
) external {
_checkAccessAllowed("setLastRewardingBlock(address[],uint32[],uint32[])");
uint256 numTokens = vTokens.length;
require(
numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,
"RewardsDistributor::setLastRewardingBlocks invalid input"
);

for (uint256 i; i < numTokens; ) {
_setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);
unchecked {
++i;
}
}
}

/**
* @notice Set REWARD TOKEN speed for a single contributor
* @param contributor The contributor whose REWARD TOKEN speed to update
Expand Down Expand Up @@ -318,6 +349,47 @@ contract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, Acce
return block.number;
}

/**
* @notice Set REWARD TOKEN last rewarding block for a single market.
* @param vToken market's whose reward token last rewarding block to be updated
* @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market
* @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market
*/
function _setLastRewardingBlock(
VToken vToken,
uint32 supplyLastRewardingBlock,
uint32 borrowLastRewardingBlock
) internal {
require(comptroller.isMarketListed(vToken), "rewardToken market is not listed");

uint256 blockNumber = getBlockNumber();

require(supplyLastRewardingBlock > blockNumber, "setting last rewarding block in the past is not allowed");
require(borrowLastRewardingBlock > blockNumber, "setting last rewarding block in the past is not allowed");

uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;
uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;

require(
currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,
"this RewardsDistributor is already locked"
);
require(
currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,
"this RewardsDistributor is already locked"
);

if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {
rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;
emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);
}

if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {
rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;
emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);
}
}

/**
* @notice Set REWARD TOKEN speed for a single market.
* @param vToken market's whose reward token rate to be updated
Expand Down Expand Up @@ -455,7 +527,13 @@ contract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, Acce
RewardToken storage supplyState = rewardTokenSupplyState[vToken];
uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];
uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits");

if (supplyState.lastRewardingBlock > 0 && blockNumber > supplyState.lastRewardingBlock) {
blockNumber = supplyState.lastRewardingBlock;
}

uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(supplyState.block));

if (deltaBlocks > 0 && supplySpeed > 0) {
uint256 supplyTokens = VToken(vToken).totalSupply();
uint256 accruedSinceUpdate = mul_(deltaBlocks, supplySpeed);
Expand Down Expand Up @@ -484,6 +562,11 @@ contract RewardsDistributor is ExponentialNoError, Ownable2StepUpgradeable, Acce
RewardToken storage borrowState = rewardTokenBorrowState[vToken];
uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];
uint32 blockNumber = safe32(getBlockNumber(), "block number exceeds 32 bits");

if (borrowState.lastRewardingBlock > 0 && blockNumber > borrowState.lastRewardingBlock) {
blockNumber = borrowState.lastRewardingBlock;
}

uint256 deltaBlocks = sub_(uint256(blockNumber), uint256(borrowState.block));
if (deltaBlocks > 0 && borrowSpeed > 0) {
uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);
Expand Down
1 change: 1 addition & 0 deletions deploy/001-deploy-mock-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
args: [token.name, token.symbol, token.decimals],
log: true,
autoMine: true, // speed up deployment on local network (ganache, hardhat), no effect on live networks
skipIfAlreadyDeployed: true,
});
}
}
Expand Down
9 changes: 9 additions & 0 deletions deploy/010-deploy-reward-distributors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer", hre);

const pools = await getUnregisteredRewardsDistributors(poolConfig, hre);

await deploy("RewardsDistributorImpl", {
contract: "RewardsDistributor",
from: deployer,
autoMine: true,
log: true,
});

for (const pool of pools) {
const rewards = pool.rewards;
if (!rewards) continue;
Expand All @@ -34,6 +42,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
from: deployer,
contract: "RewardsDistributor",
proxy: {
implementationName: `RewardsDistributorImpl`,
owner: proxyOwnerAddress,
proxyContract: "OpenZeppelinTransparentProxy",
execute: {
Expand Down
57 changes: 41 additions & 16 deletions deploy/011-initial-liquidity.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
import { BigNumber } from "ethers";
import { DeployFunction } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";

import { DeploymentConfig, PoolConfig, getConfig, getTokenConfig } from "../helpers/deploymentConfig";
import {
DeploymentConfig,
PoolConfig,
TokenConfig,
VTokenConfig,
getConfig,
getTokenConfig,
} from "../helpers/deploymentConfig";
import { getUnderlyingMock, getUnderlyingToken, getUnregisteredVTokens } from "../helpers/deploymentUtils";

const sumAmounts = async (tokens: { symbol: string; amount: BigNumber }[]) => {
const amounts: { [symbol: string]: BigNumber } = {};
for (const { symbol, amount } of tokens) {
amounts[symbol] = amount.add(amounts[symbol] || 0);
}
return amounts;
};

const faucetTokens = async (deploymentConfig: DeploymentConfig, hre: HardhatRuntimeEnvironment) => {
const { poolConfig, tokensConfig } = deploymentConfig;
const unregisteredVTokens = await getUnregisteredVTokens(poolConfig, hre);
const vTokenConfigs = unregisteredVTokens.map((p: PoolConfig) => p.vtokens).flat();
const assetsToFaucet = vTokenConfigs
.map((v: { asset: string }) => getTokenConfig(v.asset, tokensConfig))
.filter((token: TokenConfig) => token.isMock || token.faucetInitialLiquidity)
.map((token: TokenConfig) => token.symbol);

for (const vTokenConfig of vTokenConfigs) {
const token = getTokenConfig(vTokenConfig.asset, tokensConfig);
if (!token.isMock && !token.faucetInitialLiquidity) {
continue;
}
const tokenContract = await getUnderlyingMock(token.symbol);
console.log(`Minting ${vTokenConfig.initialSupply} mock ${token.symbol} to owner`);
const tx = await tokenContract.faucet(vTokenConfig.initialSupply);
const vTokensToFaucet = vTokenConfigs.filter((v: { asset: string }) => assetsToFaucet.includes(v.asset));

const amounts = vTokensToFaucet.map((token: VTokenConfig) => ({
symbol: token.asset,
amount: BigNumber.from(token.initialSupply),
}));
const totalAmounts = await sumAmounts(amounts);
for (const [symbol, amount] of Object.entries(totalAmounts)) {
const tokenContract = await getUnderlyingMock(symbol);
console.log(`Minting ${amount} mock ${symbol} to owner`);
const tx = await tokenContract.faucet(amount, { gasLimit: 5000000 });
await tx.wait(1);
}
};
Expand All @@ -29,13 +52,15 @@ const approveTimelock = async (deploymentConfig: DeploymentConfig, hre: HardhatR
const unregisteredVTokens = await getUnregisteredVTokens(poolConfig, hre);
const vTokenConfigs = unregisteredVTokens.map((p: PoolConfig) => p.vtokens).flat();

for (const vTokenConfig of vTokenConfigs) {
const { asset, initialSupply } = vTokenConfig;
const token = getTokenConfig(asset, tokensConfig);

const tokenContract = await getUnderlyingToken(token.symbol, tokensConfig);
console.log(`Approving ${initialSupply} ${token.symbol} to Timelock`);
const tx = await tokenContract.approve(preconfiguredAddresses.NormalTimelock, initialSupply);
const amounts = vTokenConfigs.map((token: VTokenConfig) => ({
symbol: token.asset,
amount: BigNumber.from(token.initialSupply),
}));
const totalAmounts = await sumAmounts(amounts);
for (const [symbol, amount] of Object.entries(totalAmounts)) {
const tokenContract = await getUnderlyingToken(symbol, tokensConfig);
console.log(`Approving ${amount} ${symbol} to Timelock`);
const tx = await tokenContract.approve(preconfiguredAddresses.NormalTimelock, amount, { gasLimit: 5000000 });
await tx.wait(1);
}
};
Expand Down
Loading