From 7ea4ffd9f43d9f7fb23fc2b5e5f5314428b6c4a3 Mon Sep 17 00:00:00 2001 From: web3rover Date: Tue, 24 Dec 2024 14:14:27 +0530 Subject: [PATCH] feat: added simulations --- .../vip-410/abi/RewardDistributor.json | 532 ++++++++++++++++++ simulations/vip-410/arbitrumone.ts | 64 +++ simulations/vip-410/bscmainnet.ts | 18 +- simulations/vip-410/ethereum.ts | 64 +++ simulations/vip-410/zksyncmainnet.ts | 64 +++ vips/vip-410/bscmainnet.ts | 53 +- 6 files changed, 747 insertions(+), 48 deletions(-) create mode 100644 simulations/vip-410/abi/RewardDistributor.json create mode 100644 simulations/vip-410/arbitrumone.ts create mode 100644 simulations/vip-410/ethereum.ts create mode 100644 simulations/vip-410/zksyncmainnet.ts diff --git a/simulations/vip-410/abi/RewardDistributor.json b/simulations/vip-410/abi/RewardDistributor.json new file mode 100644 index 000000000..249fdd111 --- /dev/null +++ b/simulations/vip-410/abi/RewardDistributor.json @@ -0,0 +1,532 @@ +[ + { + "inputs": [ + { "internalType": "bool", "name": "timeBased_", "type": "bool" }, + { "internalType": "uint256", "name": "blocksPerYear_", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "InvalidBlocksPerYear", "type": "error" }, + { "inputs": [], "name": "InvalidTimeBasedConfiguration", "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" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "vToken", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "newTimestamp", "type": "uint256" } + ], + "name": "BorrowLastRewardingBlockTimestampUpdated", + "type": "event" + }, + { + "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": "uint256", "name": "newTimestamp", "type": "uint256" } + ], + "name": "SupplyLastRewardingBlockTimestampUpdated", + "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": [], + "name": "blocksOrSecondsPerYear", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "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": "getBlockNumberOrTimestamp", + "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": [], + "name": "isTimeBased", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "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" }], + "name": "rewardTokenBorrowStateTimeBased", + "outputs": [ + { "internalType": "uint224", "name": "index", "type": "uint224" }, + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { "internalType": "uint256", "name": "lastRewardingTimestamp", "type": "uint256" } + ], + "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": "", "type": "address" }], + "name": "rewardTokenSupplyStateTimeBased", + "outputs": [ + { "internalType": "uint224", "name": "index", "type": "uint224" }, + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { "internalType": "uint256", "name": "lastRewardingTimestamp", "type": "uint256" } + ], + "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": "uint256[]", "name": "supplyLastRewardingBlockTimestamps", "type": "uint256[]" }, + { "internalType": "uint256[]", "name": "borrowLastRewardingBlockTimestamps", "type": "uint256[]" } + ], + "name": "setLastRewardingBlockTimestamps", + "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" + } +] diff --git a/simulations/vip-410/arbitrumone.ts b/simulations/vip-410/arbitrumone.ts new file mode 100644 index 000000000..3644926be --- /dev/null +++ b/simulations/vip-410/arbitrumone.ts @@ -0,0 +1,64 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { LzChainId } from "src/types"; +import { expectEvents } from "src/utils"; +import { forking, testForkedNetworkVipCommands } from "src/vip-framework"; + +import vip410, { + ARBITRUM_XVS, + ARBITRUM_XVS_VAULT, + ARBITRUM_XVS_VAULT_REWARD, + emissions, +} from "../../vips/vip-410/bscmainnet"; +import REWARDS_DISTRIBUTOR_ABI from "./abi/RewardDistributor.json"; +import XVS_VAULT_ABI from "./abi/XVSVault.json"; + +forking(288053557, async () => { + testForkedNetworkVipCommands("VIP 403 Multichain Governance - Permissions", await vip410(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [REWARDS_DISTRIBUTOR_ABI], + ["RewardTokenSupplySpeedUpdated", "RewardTokenBorrowSpeedUpdated"], + [7, 6], + ); + await expectEvents(txResponse, [XVS_VAULT_ABI], ["RewardAmountUpdated"], [1]); + }, + }); + + describe("Post-VIP behaviour", async () => { + it("Check reward distirbutor speed", async () => { + for (const { + chainId, + newAllocation, + isSupplierAllocation, + isBorrowerAllocation, + vToken, + rewardsDistributor, + blocksPerMonth, + } of emissions) { + if (chainId == LzChainId.arbitrumone) { + const rewardDistirbutor = new ethers.Contract(rewardsDistributor, REWARDS_DISTRIBUTOR_ABI, ethers.provider); + if (isSupplierAllocation) { + expect(await rewardDistirbutor.rewardTokenSupplySpeeds(vToken)).to.equals( + newAllocation.div(blocksPerMonth), + ); + expect(await rewardDistirbutor.rewardTokenBorrowSpeeds(vToken)).to.equals(0); + } + + if (isBorrowerAllocation) { + expect(await rewardDistirbutor.rewardTokenSupplySpeeds(vToken)).to.equals(0); + expect(await rewardDistirbutor.rewardTokenBorrowSpeeds(vToken)).to.equals( + newAllocation.div(blocksPerMonth), + ); + } + } + } + }); + + it("check xvs vault speed", async () => { + const xvsVault = new ethers.Contract(ARBITRUM_XVS_VAULT, XVS_VAULT_ABI, ethers.provider); + expect(await xvsVault.rewardTokenAmountsPerBlockOrSecond(ARBITRUM_XVS)).to.equals(ARBITRUM_XVS_VAULT_REWARD); + }); + }); +}); diff --git a/simulations/vip-410/bscmainnet.ts b/simulations/vip-410/bscmainnet.ts index cf9889de4..b8cd04adc 100644 --- a/simulations/vip-410/bscmainnet.ts +++ b/simulations/vip-410/bscmainnet.ts @@ -1,14 +1,14 @@ import { TransactionResponse } from "@ethersproject/providers"; +import { expect } from "chai"; +import { Contract } from "ethers"; +import { ethers } from "hardhat"; import { expectEvents } from "src/utils"; import { forking, testVip } from "src/vip-framework"; -import vip410, {BSC_XVS_VAULT, BSC_COMPTROLLER, BSC_XVS, BSC_XVS_MARKET} from "../../vips/vip-410/bscmainnet"; +import vip410, { BSC_COMPTROLLER, BSC_XVS, BSC_XVS_MARKET, BSC_XVS_VAULT } from "../../vips/vip-410/bscmainnet"; import OMNICHAIN_PROPOSAL_SENDER_ABI from "./abi/OmnichainProposalSender.json"; import XVS_VAULT_ABI from "./abi/XVSVault.json"; import COMPTROLLER_ABI from "./abi/comptroller.json"; -import { Contract } from "ethers"; -import { ethers } from "hardhat"; -import { expect } from "chai"; forking(45126615, async () => { let comptroller: Contract; @@ -26,11 +26,11 @@ forking(45126615, async () => { it("check VAI vault rate", async () => { expect(await comptroller.venusVAIVaultRate()).to.equals("4340277777777780"); - }) + }); it("check XVS market speed", async () => { expect(await comptroller.venusSupplySpeeds(BSC_XVS_MARKET)).to.equals("1388888888888888"); - }) + }); }); testVip("vip-410", await vip410(), { @@ -58,10 +58,10 @@ forking(45126615, async () => { it("check VAI vault rate", async () => { expect(await comptroller.venusVAIVaultRate()).to.equals("3255787037037037"); - }) + }); it("check XVS market speed", async () => { expect(await comptroller.venusSupplySpeeds(BSC_XVS_MARKET)).to.equals("1027397260273972"); - }) - }) + }); + }); }); diff --git a/simulations/vip-410/ethereum.ts b/simulations/vip-410/ethereum.ts new file mode 100644 index 000000000..8381ef599 --- /dev/null +++ b/simulations/vip-410/ethereum.ts @@ -0,0 +1,64 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { LzChainId } from "src/types"; +import { expectEvents } from "src/utils"; +import { forking, testForkedNetworkVipCommands } from "src/vip-framework"; + +import vip410, { + ETHEREYM_XVS, + ETHEREYM_XVS_VAULT, + ETHEREYM_XVS_VAULT_REWARD, + emissions, +} from "../../vips/vip-410/bscmainnet"; +import REWARDS_DISTRIBUTOR_ABI from "./abi/RewardDistributor.json"; +import XVS_VAULT_ABI from "./abi/XVSVault.json"; + +forking(21470971, async () => { + testForkedNetworkVipCommands("VIP 403 Multichain Governance - Permissions", await vip410(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [REWARDS_DISTRIBUTOR_ABI], + ["RewardTokenSupplySpeedUpdated", "RewardTokenBorrowSpeedUpdated"], + [5, 5], + ); + await expectEvents(txResponse, [XVS_VAULT_ABI], ["RewardAmountUpdated"], [1]); + }, + }); + + describe("Post-VIP behaviour", async () => { + it("Check reward distirbutor speed", async () => { + for (const { + chainId, + newAllocation, + isSupplierAllocation, + isBorrowerAllocation, + vToken, + rewardsDistributor, + blocksPerMonth, + } of emissions) { + if (chainId == LzChainId.ethereum) { + const rewardDistirbutor = new ethers.Contract(rewardsDistributor, REWARDS_DISTRIBUTOR_ABI, ethers.provider); + if (isSupplierAllocation) { + expect(await rewardDistirbutor.rewardTokenSupplySpeeds(vToken)).to.equals( + newAllocation.div(blocksPerMonth), + ); + expect(await rewardDistirbutor.rewardTokenBorrowSpeeds(vToken)).to.equals(0); + } + + if (isBorrowerAllocation) { + expect(await rewardDistirbutor.rewardTokenSupplySpeeds(vToken)).to.equals(0); + expect(await rewardDistirbutor.rewardTokenBorrowSpeeds(vToken)).to.equals( + newAllocation.div(blocksPerMonth), + ); + } + } + } + }); + + it("check xvs vault speed", async () => { + const xvsVault = new ethers.Contract(ETHEREYM_XVS_VAULT, XVS_VAULT_ABI, ethers.provider); + expect(await xvsVault.rewardTokenAmountsPerBlockOrSecond(ETHEREYM_XVS)).to.equals(ETHEREYM_XVS_VAULT_REWARD); + }); + }); +}); diff --git a/simulations/vip-410/zksyncmainnet.ts b/simulations/vip-410/zksyncmainnet.ts new file mode 100644 index 000000000..5aa27e0ce --- /dev/null +++ b/simulations/vip-410/zksyncmainnet.ts @@ -0,0 +1,64 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { LzChainId } from "src/types"; +import { expectEvents } from "src/utils"; +import { forking, testForkedNetworkVipCommands } from "src/vip-framework"; + +import vip410, { + ZKSYNC_XVS, + ZKSYNC_XVS_VAULT, + ZKSYNC_XVS_VAULT_REWARD, + emissions, +} from "../../vips/vip-410/bscmainnet"; +import REWARDS_DISTRIBUTOR_ABI from "./abi/RewardDistributor.json"; +import XVS_VAULT_ABI from "./abi/XVSVault.json"; + +forking(52050098, async () => { + testForkedNetworkVipCommands("VIP 403 Multichain Governance - Permissions", await vip410(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [REWARDS_DISTRIBUTOR_ABI], + ["RewardTokenSupplySpeedUpdated", "RewardTokenBorrowSpeedUpdated"], + [7, 6], + ); + await expectEvents(txResponse, [XVS_VAULT_ABI], ["RewardAmountUpdated"], [1]); + }, + }); + + describe("Post-VIP behaviour", async () => { + it("Check reward distirbutor speed", async () => { + for (const { + chainId, + newAllocation, + isSupplierAllocation, + isBorrowerAllocation, + vToken, + rewardsDistributor, + blocksPerMonth, + } of emissions) { + if (chainId == LzChainId.zksyncmainnet) { + const rewardDistirbutor = new ethers.Contract(rewardsDistributor, REWARDS_DISTRIBUTOR_ABI, ethers.provider); + if (isSupplierAllocation) { + expect(await rewardDistirbutor.rewardTokenSupplySpeeds(vToken)).to.equals( + newAllocation.div(blocksPerMonth), + ); + expect(await rewardDistirbutor.rewardTokenBorrowSpeeds(vToken)).to.equals(0); + } + + if (isBorrowerAllocation) { + expect(await rewardDistirbutor.rewardTokenSupplySpeeds(vToken)).to.equals(0); + expect(await rewardDistirbutor.rewardTokenBorrowSpeeds(vToken)).to.equals( + newAllocation.div(blocksPerMonth), + ); + } + } + } + }); + + it("check xvs vault speed", async () => { + const xvsVault = new ethers.Contract(ZKSYNC_XVS_VAULT, XVS_VAULT_ABI, ethers.provider); + expect(await xvsVault.rewardTokenAmountsPerBlockOrSecond(ZKSYNC_XVS)).to.equals(ZKSYNC_XVS_VAULT_REWARD); + }); + }); +}); diff --git a/vips/vip-410/bscmainnet.ts b/vips/vip-410/bscmainnet.ts index cd0a2e751..44763430e 100644 --- a/vips/vip-410/bscmainnet.ts +++ b/vips/vip-410/bscmainnet.ts @@ -1,11 +1,10 @@ -import { parseUnits } from "ethers/lib/utils"; import { ethers } from "hardhat"; +import { LzChainId } from "src/types"; import { ProposalType } from "../../src/types"; import { makeProposal } from "../../src/utils"; -import { LzChainId } from "src/types"; -export const ZKSYNC_BLOCKS_PER_MONTH = 2592000; +export const ZKSYNC_BLOCKS_PER_MONTH = 2592000; export const ARBITRUM_BLOCKS_PER_MONTH = 2592000; export const ETHEREUM_BLOCKS_PER_MONTH = 216000; export const BSC_BLOCKS_PER_MONTH = 876000; @@ -24,7 +23,7 @@ export const BSC_XVS_VAULT = "0x051100480289e704d20e9DB4804837068f3f9204"; export const ZKSYNC_XVS = "0xD78ABD81a3D57712a3af080dc4185b698Fe9ac5A"; export const ETHEREYM_XVS = "0xd3CC9d8f3689B83c91b7B59cAB4946B063EB894A"; export const ARBITRUM_XVS = "0xc1Eb7689147C81aC840d4FF0D298489fc7986d52"; -export const BSC_XVS = "0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63" +export const BSC_XVS = "0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63"; export const ZKSYNC_XVS_VAULT_REWARD = "405092592592592"; export const ETHEREYM_XVS_VAULT_REWARD = "23333333333333333"; @@ -37,10 +36,9 @@ export const BSC_COMPTROLLER = "0xfD36E2c2a6789Db23113685031d7F16329158384"; export const BSC_VAI_VAULT_RATE = "3255787037037037"; export const BSC_XVS_VAULT_RATE = "15312500000000000"; -const emissions = [ +export const emissions = [ { chainId: LzChainId.zksyncmainnet, - currentAllocation: ethers.utils.parseEther("900"), newAllocation: ethers.utils.parseEther("630"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -50,7 +48,6 @@ const emissions = [ }, { chainId: LzChainId.zksyncmainnet, - currentAllocation: ethers.utils.parseEther("1200"), newAllocation: ethers.utils.parseEther("600"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -60,7 +57,6 @@ const emissions = [ }, { chainId: LzChainId.zksyncmainnet, - currentAllocation: ethers.utils.parseEther("1200"), newAllocation: ethers.utils.parseEther("600"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -70,7 +66,6 @@ const emissions = [ }, { chainId: LzChainId.zksyncmainnet, - currentAllocation: ethers.utils.parseEther("900"), newAllocation: ethers.utils.parseEther("450"), isSupplierAllocation: false, isBorrowerAllocation: true, @@ -80,7 +75,6 @@ const emissions = [ }, { chainId: LzChainId.zksyncmainnet, - currentAllocation: ethers.utils.parseEther("1800"), newAllocation: ethers.utils.parseEther("900"), isSupplierAllocation: false, isBorrowerAllocation: true, @@ -90,7 +84,6 @@ const emissions = [ }, { chainId: LzChainId.ethereum, - currentAllocation: ethers.utils.parseEther("633"), newAllocation: ethers.utils.parseEther("475"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -100,7 +93,6 @@ const emissions = [ }, { chainId: LzChainId.ethereum, - currentAllocation: ethers.utils.parseEther("1898"), newAllocation: ethers.utils.parseEther("949"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -110,7 +102,6 @@ const emissions = [ }, { chainId: LzChainId.ethereum, - currentAllocation: ethers.utils.parseEther("2279"), newAllocation: ethers.utils.parseEther("1709"), isSupplierAllocation: false, isBorrowerAllocation: true, @@ -120,7 +111,6 @@ const emissions = [ }, { chainId: LzChainId.ethereum, - currentAllocation: ethers.utils.parseEther("2279"), newAllocation: ethers.utils.parseEther("1709"), isSupplierAllocation: false, isBorrowerAllocation: true, @@ -130,7 +120,6 @@ const emissions = [ }, { chainId: LzChainId.ethereum, - currentAllocation: ethers.utils.parseEther("12375"), newAllocation: ethers.utils.parseEther("3713"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -140,7 +129,6 @@ const emissions = [ }, { chainId: LzChainId.arbitrumone, - currentAllocation: ethers.utils.parseEther("319"), newAllocation: ethers.utils.parseEther("239"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -150,7 +138,6 @@ const emissions = [ }, { chainId: LzChainId.arbitrumone, - currentAllocation: ethers.utils.parseEther("319"), newAllocation: ethers.utils.parseEther("239"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -160,7 +147,6 @@ const emissions = [ }, { chainId: LzChainId.arbitrumone, - currentAllocation: ethers.utils.parseEther("638"), newAllocation: ethers.utils.parseEther("319"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -170,7 +156,6 @@ const emissions = [ }, { chainId: LzChainId.arbitrumone, - currentAllocation: ethers.utils.parseEther("638"), newAllocation: ethers.utils.parseEther("479"), isSupplierAllocation: false, isBorrowerAllocation: true, @@ -180,7 +165,6 @@ const emissions = [ }, { chainId: LzChainId.arbitrumone, - currentAllocation: ethers.utils.parseEther("638"), newAllocation: ethers.utils.parseEther("479"), isSupplierAllocation: false, isBorrowerAllocation: true, @@ -190,7 +174,6 @@ const emissions = [ }, { chainId: LzChainId.arbitrumone, - currentAllocation: ethers.utils.parseEther("3400"), newAllocation: ethers.utils.parseEther("1020"), isSupplierAllocation: true, isBorrowerAllocation: false, @@ -200,7 +183,6 @@ const emissions = [ }, { chainId: LzChainId.arbitrumone, - currentAllocation: ethers.utils.parseEther("850"), newAllocation: ethers.utils.parseEther("0"), isSupplierAllocation: false, isBorrowerAllocation: false, @@ -210,7 +192,6 @@ const emissions = [ }, { chainId: LzChainId.arbitrumone, - currentAllocation: ethers.utils.parseEther("850"), newAllocation: ethers.utils.parseEther("0"), isSupplierAllocation: false, isBorrowerAllocation: false, @@ -218,7 +199,7 @@ const emissions = [ rewardsDistributor: ARBITRUM_XVS_REWARDS_DISTRIBUTOR_LST, blocksPerMonth: ARBITRUM_BLOCKS_PER_MONTH, }, -] +]; const commands = emissions.map(emission => { const speed = emission.newAllocation.div(emission.blocksPerMonth); @@ -230,9 +211,9 @@ const commands = emissions.map(emission => { [emission.isSupplierAllocation ? speed : 0], [emission.isBorrowerAllocation ? speed : 0], ], - dstChainId: emission.chainId + dstChainId: emission.chainId, }; -}) +}); export const vip410 = () => { const meta = { @@ -251,45 +232,39 @@ export const vip410 = () => { target: ZKSYNC_XVS_VAULT, signature: "setRewardAmountPerBlockOrSecond(address,uint256)", params: [ZKSYNC_XVS, ZKSYNC_XVS_VAULT_REWARD], - dstChainId: LzChainId.zksyncmainnet + dstChainId: LzChainId.zksyncmainnet, }, { target: ETHEREYM_XVS_VAULT, signature: "setRewardAmountPerBlockOrSecond(address,uint256)", params: [ETHEREYM_XVS, ETHEREYM_XVS_VAULT_REWARD], - dstChainId: LzChainId.ethereum + dstChainId: LzChainId.ethereum, }, { target: ARBITRUM_XVS_VAULT, signature: "setRewardAmountPerBlockOrSecond(address,uint256)", params: [ARBITRUM_XVS, ARBITRUM_XVS_VAULT_REWARD], - dstChainId: LzChainId.arbitrumone + dstChainId: LzChainId.arbitrumone, }, { target: BSC_COMPTROLLER, signature: "_setVenusSpeeds(address[],uint256[],uint256[])", - params: [ - [BSC_XVS_MARKET], - [BSC_XVS_MARKET_SUPPLY_REWARD_MONTHLY.div(BSC_BLOCKS_PER_MONTH)], - [0], - ], + params: [[BSC_XVS_MARKET], [BSC_XVS_MARKET_SUPPLY_REWARD_MONTHLY.div(BSC_BLOCKS_PER_MONTH)], [0]], }, { target: BSC_COMPTROLLER, signature: "_setVenusVAIVaultRate(uint256)", - params: [ - BSC_VAI_VAULT_RATE - ], + params: [BSC_VAI_VAULT_RATE], }, { target: BSC_XVS_VAULT, signature: "setRewardAmountPerBlockOrSecond(address,uint256)", params: [BSC_XVS, BSC_XVS_VAULT_RATE], - } + }, ], meta, ProposalType.REGULAR, ); }; -export default vip410; \ No newline at end of file +export default vip410;