From af5c84d5f0d686bd1c2c83aba424408523dfd5ee Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Fri, 3 Dec 2021 17:44:58 +1100 Subject: [PATCH 1/6] feat: Added DisperseForwarder chore: Added Keeper to Nexus for operations tasks --- contracts/buy-and-make/RevenueBuyBack.sol | 17 +-- contracts/buy-and-make/RevenueForwarder.sol | 11 +- contracts/emissions/DisperseForwarder.sol | 62 ++++++++++ contracts/interfaces/IDisperse.sol | 8 ++ contracts/shared/ImmutableModule.sol | 22 ++++ contracts/shared/ModuleKeys.sol | 3 + contracts/z_mocks/nexus/MockNexus.sol | 4 + tasks/deployEmissionsController.ts | 25 ++-- tasks/utils/emissions-utils.ts | 43 ++++--- tasks/utils/tokens.ts | 12 ++ .../emissions-mainnet-deployment.spec.ts | 54 ++++++--- test-utils/machines/standardAccounts.ts | 3 + test/buy-and-make/revenue-buy-back.spec.ts | 30 ++--- test/buy-and-make/revenue-forwarder.spec.ts | 50 ++------ test/emissions/emission-controller.spec.ts | 110 ++++++++++-------- 15 files changed, 276 insertions(+), 178 deletions(-) create mode 100644 contracts/emissions/DisperseForwarder.sol create mode 100644 contracts/interfaces/IDisperse.sol diff --git a/contracts/buy-and-make/RevenueBuyBack.sol b/contracts/buy-and-make/RevenueBuyBack.sol index 0427ecd2..5cffcd2c 100644 --- a/contracts/buy-and-make/RevenueBuyBack.sol +++ b/contracts/buy-and-make/RevenueBuyBack.sol @@ -59,18 +59,11 @@ contract RevenueBuyBack is IRevenueRecipient, Initializable, ImmutableModule { /// @notice Uniswap V3 Router address IUniswapV3SwapRouter public immutable UNISWAP_ROUTER; - /// @notice Account that can execute `buyBackRewards`. eg Operations account. - address public keeper; /// @notice Mapping of mAssets to RevenueBuyBack config mapping(address => RevenueBuyBackConfig) public massetConfig; /// @notice Emissions Controller dial ids for all staking contracts that will receive reward tokens. uint256[] public stakingDialIds; - modifier keeperOrGovernor() { - require(msg.sender == keeper || msg.sender == _governor(), "Only keeper or governor"); - _; - } - /** * @param _nexus mStable system Nexus address * @param _rewardsToken Rewards token address that are purchased. eg MTA @@ -94,13 +87,9 @@ contract RevenueBuyBack is IRevenueRecipient, Initializable, ImmutableModule { } /** - * @param _keeper Account that can execute `buyBackRewards`. eg Operations account. * @param _stakingDialIds Emissions Controller dial ids for all staking contracts that will receive reward tokens. */ - function initialize(address _keeper, uint16[] memory _stakingDialIds) external initializer { - require(_keeper != address(0), "Keeper is zero"); - keeper = _keeper; - + function initialize(uint16[] memory _stakingDialIds) external initializer { for (uint256 i = 0; i < _stakingDialIds.length; i++) { _addStakingContract(_stakingDialIds[i]); } @@ -128,7 +117,7 @@ contract RevenueBuyBack is IRevenueRecipient, Initializable, ImmutableModule { * @notice Buys reward tokens, eg MTA, using mAssets like mUSD or mBTC from protocol revenue. * @param _mAssets Addresses of mAssets that are to be sold for rewards. eg mUSD and mBTC. */ - function buyBackRewards(address[] calldata _mAssets) external keeperOrGovernor { + function buyBackRewards(address[] calldata _mAssets) external onlyKeeperOrGovernor { uint256 len = _mAssets.length; require(len > 0, "Invalid args"); @@ -170,7 +159,7 @@ contract RevenueBuyBack is IRevenueRecipient, Initializable, ImmutableModule { /** * @notice donates purchased rewards, eg MTA, to staking contracts via the Emissions Controller. */ - function donateRewards() external keeperOrGovernor { + function donateRewards() external onlyKeeperOrGovernor { // STEP 1 - Get the voting power of the staking contracts uint256 numberStakingContracts = stakingDialIds.length; uint256[] memory votingPower = new uint256[](numberStakingContracts); diff --git a/contracts/buy-and-make/RevenueForwarder.sol b/contracts/buy-and-make/RevenueForwarder.sol index 29f1285c..d28d39a4 100644 --- a/contracts/buy-and-make/RevenueForwarder.sol +++ b/contracts/buy-and-make/RevenueForwarder.sol @@ -22,29 +22,20 @@ contract RevenueForwarder is IRevenueRecipient, ImmutableModule { IERC20 public immutable mAsset; - address public immutable keeper; address public forwarder; constructor( address _nexus, address _mAsset, - address _keeper, address _forwarder ) ImmutableModule(_nexus) { require(_mAsset != address(0), "mAsset is zero"); - require(_keeper != address(0), "Keeper is zero"); require(_forwarder != address(0), "Forwarder is zero"); mAsset = IERC20(_mAsset); - keeper = _keeper; forwarder = _forwarder; } - modifier keeperOrGovernor() { - require(msg.sender == keeper || msg.sender == _governor(), "Only keeper or governor"); - _; - } - /** * @dev Simply transfers the mAsset from the sender to here * @param _mAsset Address of mAsset @@ -61,7 +52,7 @@ contract RevenueForwarder is IRevenueRecipient, ImmutableModule { /** * @dev Withdraws to forwarder */ - function forward() external keeperOrGovernor { + function forward() external onlyKeeperOrGovernor { uint256 amt = mAsset.balanceOf(address(this)); if (amt == 0) { return; diff --git a/contracts/emissions/DisperseForwarder.sol b/contracts/emissions/DisperseForwarder.sol new file mode 100644 index 00000000..01bf2c4c --- /dev/null +++ b/contracts/emissions/DisperseForwarder.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.6; + +import { IERC20, SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { IDisperse } from "../interfaces/IDisperse.sol"; +import { ImmutableModule } from "../shared/ImmutableModule.sol"; + +/** + * @title DisperseForwarder + * @author mStable + * @notice Transfers reward tokens to a list of off-chain calculated recipients and amounts. + * @dev Disperse contract on Mainnet and Polygon: 0xD152f549545093347A162Dce210e7293f1452150 + * @dev VERSION: 1.0 + * DATE: 2021-11-03 + */ +contract DisperseForwarder is ImmutableModule { + using SafeERC20 for IERC20; + + /// @notice Rewards token that is to be dispersed. + IERC20 public immutable REWARDS_TOKEN; + /// @notice Token Disperser contract. eg 0xD152f549545093347A162Dce210e7293f1452150 + IDisperse public immutable DISPERSE; + + /** + * @param _rewardsToken Bridged rewards token on the Polygon chain. + * @param _disperse Token disperser contract. + */ + constructor(address _nexus, address _rewardsToken, address _disperse) + ImmutableModule(_nexus) { + require(_rewardsToken != address(0), "Invalid Rewards token"); + require(_disperse != address(0), "Invalid Disperse contract"); + + REWARDS_TOKEN = IERC20(_rewardsToken); + DISPERSE = IDisperse(_disperse); + + } + + /** + * @notice Transfers reward tokens to a list of recipients with amounts. + * @param recipients Array of address that are to receive token rewards. + * @param values Array of reward token amounts for each recipient including decimal places. + */ + function disperseToken(address[] memory recipients, uint256[] memory values) external onlyKeeperOrGovernor { + uint256 len = recipients.length; + require(values.length == len, "array mismatch"); + + // Calculate the total amount of rewards that will be dispersed. + uint256 total = 0; + for (uint256 i = 0; i < len; i++) { + total += values[i]; + } + + uint256 rewardBal = REWARDS_TOKEN.balanceOf(address(this)); + require(rewardBal >= total, "Insufficient rewards"); + + // Approve only the amount to be dispersed. Any more and the funds in this contract can be stolen + // using the disperseTokenSimple function on the Disperse contract. + REWARDS_TOKEN.safeApprove(address(DISPERSE), total); + + DISPERSE.disperseTokenSimple(REWARDS_TOKEN, recipients, values); + } +} diff --git a/contracts/interfaces/IDisperse.sol b/contracts/interfaces/IDisperse.sol new file mode 100644 index 00000000..5e6b8fc2 --- /dev/null +++ b/contracts/interfaces/IDisperse.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.6; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +interface IDisperse { + function disperseTokenSimple(IERC20 token, address[] memory recipients, uint256[] memory values) external; +} diff --git a/contracts/shared/ImmutableModule.sol b/contracts/shared/ImmutableModule.sol index 1b408aca..8c3ab790 100644 --- a/contracts/shared/ImmutableModule.sol +++ b/contracts/shared/ImmutableModule.sol @@ -34,6 +34,18 @@ abstract contract ImmutableModule is ModuleKeys { require(msg.sender == _governor(), "Only governor can execute"); } + /** + * @dev Modifier to allow function calls only from the Governor or the Keeper EOA. + */ + modifier onlyKeeperOrGovernor() { + _keeperOrGovernor(); + _; + } + + function _keeperOrGovernor() internal view { + require(msg.sender == _keeper() || msg.sender == _governor(), "Only keeper or governor"); + } + /** * @dev Modifier to allow function calls only from the Governance. * Governance is either Governor address or Governance address. @@ -62,6 +74,16 @@ abstract contract ImmutableModule is ModuleKeys { return nexus.getModule(KEY_GOVERNANCE); } + /** + * @dev Return Keeper address from the Nexus. + * This account is used for operational transactions that + * don't need multiple signatures. + * @return Address of the Keeper externally owned account. + */ + function _keeper() internal view returns (address) { + return nexus.getModule(KEY_KEEPER); + } + /** * @dev Return SavingsManager Module address from the Nexus * @return Address of the SavingsManager Module contract diff --git a/contracts/shared/ModuleKeys.sol b/contracts/shared/ModuleKeys.sol index cfd7dd84..ff28b798 100644 --- a/contracts/shared/ModuleKeys.sol +++ b/contracts/shared/ModuleKeys.sol @@ -45,4 +45,7 @@ contract ModuleKeys { // keccak256("InterestValidator"); bytes32 internal constant KEY_INTEREST_VALIDATOR = 0xc10a28f028c7f7282a03c90608e38a4a646e136e614e4b07d119280c5f7f839f; + // keccak256("Keeper"); + bytes32 internal constant KEY_KEEPER = + 0x4f78afe9dfc9a0cb0441c27b9405070cd2a48b490636a7bdd09f355e33a5d7de; } diff --git a/contracts/z_mocks/nexus/MockNexus.sol b/contracts/z_mocks/nexus/MockNexus.sol index 54182e9f..a53a7df6 100644 --- a/contracts/z_mocks/nexus/MockNexus.sol +++ b/contracts/z_mocks/nexus/MockNexus.sol @@ -43,4 +43,8 @@ contract MockNexus is ModuleKeys { function setRecollateraliser(address _recollateraliser) external { modules[KEY_RECOLLATERALISER] = _recollateraliser; } + + function setKeeper(address _keeper) external { + modules[KEY_KEEPER] = _keeper; + } } diff --git a/tasks/deployEmissionsController.ts b/tasks/deployEmissionsController.ts index bb4d95ca..3c794e62 100644 --- a/tasks/deployEmissionsController.ts +++ b/tasks/deployEmissionsController.ts @@ -7,6 +7,7 @@ import { getSigner } from "./utils/signerFactory" import { deployBasicForwarder, deployBridgeForwarder, + deployDisperseForwarder, deployEmissionsController, deployL2BridgeRecipients, deployL2EmissionsController, @@ -22,10 +23,13 @@ task("deploy-emissions-polly", "Deploys L2EmissionsController and L2 Bridge Reci const signer = await getSigner(hre, taskArgs.speed) const l2EmissionsController = await deployL2EmissionsController(signer, hre) + console.log(`Set L2EmissionsController contract name in networkAddressFactory to ${l2EmissionsController.address}`) - await deployL2BridgeRecipients(signer, hre, l2EmissionsController.address) + const bridgeRecipient = await deployL2BridgeRecipients(signer, hre, l2EmissionsController.address) + console.log(`Set PmUSD bridgeRecipient to ${bridgeRecipient.address}`) - console.log(`Set L2EmissionsController contract name in networkAddressFactory to ${l2EmissionsController.address}`) + const disperseForwarder = await deployDisperseForwarder(signer, hre) + console.log(`Set PBAL bridgeRecipient to ${disperseForwarder.address}`) }) task("deploy-emissions") @@ -37,20 +41,21 @@ task("deploy-emissions") console.log(`Set RewardsDistributor in the networkAddressFactory to ${emissionsController.address}`) }) -task("deploy-bridge-forwarders", "Deploys Polygon mUSD Vault and FRAX BridgeForwarders on mainnet") +task("deploy-bridge-forwarder", "Deploys a BridgeForwarder contract on mainnet for Polygon dials.") + .addParam( + "token", + "Token on the Polygon network that is configured with `bridgeRecipient`. eg mUSD, FRAX, BAL.", + undefined, + types.string, + ) .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", types.string) .setAction(async (taskArgs, hre) => { const chain = getChain(hre) const signer = await getSigner(hre, taskArgs.speed) const l2Chain = chain === Chain.mainnet ? Chain.polygon : Chain.mumbai - const mUSDBridgeRecipientAddress = resolveAddress("mUSD", l2Chain, "bridgeRecipient") - await deployBridgeForwarder(signer, hre, mUSDBridgeRecipientAddress) - - if (chain === Chain.mainnet) { - const fraxBridgeRecipientAddress = resolveAddress("FRAX", l2Chain, "bridgeRecipient") - await deployBridgeForwarder(signer, hre, fraxBridgeRecipientAddress) - } + const bridgeRecipientAddress = resolveAddress(taskArgs.token, l2Chain, "bridgeRecipient") + await deployBridgeForwarder(signer, hre, bridgeRecipientAddress) }) task("deploy-basic-forwarder", "Deploys a basic rewards forwarder from the emissions controller.") diff --git a/tasks/utils/emissions-utils.ts b/tasks/utils/emissions-utils.ts index c75f83a9..913d0972 100644 --- a/tasks/utils/emissions-utils.ts +++ b/tasks/utils/emissions-utils.ts @@ -6,6 +6,8 @@ import { BasicRewardsForwarder__factory, BridgeForwarder, BridgeForwarder__factory, + DisperseForwarder, + DisperseForwarder__factory, EmissionsController, EmissionsController__factory, L2BridgeRecipient, @@ -167,35 +169,39 @@ export const deployL2BridgeRecipients = async ( signer: Signer, hre: HardhatRuntimeEnvironment, l2EmissionsControllerAddress: string, -): Promise => { +): Promise => { const mtaAddress = MTA.address const constructorArguments = [mtaAddress, l2EmissionsControllerAddress] - const mUSDBridgeRecipient = await deployContract( - new L2BridgeRecipient__factory(signer), - "mUSD Vault Bridge Recipient", - [mtaAddress, l2EmissionsControllerAddress], - ) - console.log(`Set PmUSD bridgeRecipient to ${mUSDBridgeRecipient.address}`) + const bridgeRecipient = await deployContract(new L2BridgeRecipient__factory(signer), "L2BridgeRecipient", [ + mtaAddress, + l2EmissionsControllerAddress, + ]) + await verifyEtherscan(hre, { - address: mUSDBridgeRecipient.address, + address: bridgeRecipient.address, constructorArguments, contract: "contracts/emissions/L2BridgeRecipient.sol:L2BridgeRecipient", }) - const fraxBridgeRecipient = await deployContract( - new L2BridgeRecipient__factory(signer), - "FRAX Farm Bridge Recipient", - [mtaAddress, l2EmissionsControllerAddress], - ) - console.log(`Set PFRAX bridgeRecipient to ${fraxBridgeRecipient.address}`) + return bridgeRecipient +} + +export const deployDisperseForwarder = async (signer: Signer, hre: HardhatRuntimeEnvironment): Promise => { + const mtaAddress = MTA.address + const constructorArguments = [mtaAddress] + + const disperseForwarder = await deployContract(new DisperseForwarder__factory(signer), "DisperseForwarder", [ + mtaAddress, + ]) + await verifyEtherscan(hre, { - address: fraxBridgeRecipient.address, + address: disperseForwarder.address, constructorArguments, - contract: "contracts/emissions/L2BridgeRecipient.sol:L2BridgeRecipient", + contract: "contracts/emissions/DisperseForwarder.sol:DisperseForwarder", }) - return [mUSDBridgeRecipient, fraxBridgeRecipient] + return disperseForwarder } export const deployBridgeForwarder = async ( @@ -256,7 +262,6 @@ export const deployRevenueBuyBack = async ( const mtaAddress = MTA.address const uniswapRouterAddress = resolveAddress("UniswapRouterV3", chain) const emissionsControllerAddress = _emissionsControllerAddress || resolveAddress("EmissionsController", chain) - const devOpsAddress = resolveAddress("OperationsSigner", chain) // Deploy RevenueBuyBack const constructorArguments: [string, string, string, string] = [ @@ -266,7 +271,7 @@ export const deployRevenueBuyBack = async ( emissionsControllerAddress, ] const revenueBuyBack = await new RevenueBuyBack__factory(signer).deploy(...constructorArguments) - await revenueBuyBack.initialize(devOpsAddress, [0, 1]) + await revenueBuyBack.initialize([0, 1]) await verifyEtherscan(hre, { address: revenueBuyBack.address, diff --git a/tasks/utils/tokens.ts b/tasks/utils/tokens.ts index b9400322..49f44fee 100644 --- a/tasks/utils/tokens.ts +++ b/tasks/utils/tokens.ts @@ -472,6 +472,17 @@ export const BAL: Token = { quantityFormatter: "USD", } +export const PBAL: Token = { + symbol: "BAL", + address: "0x9a71012B13CA4d3D0Cdc72A177DF3ef03b0E76A3", + chain: Chain.polygon, + decimals: 18, + quantityFormatter: "USD", + bridgeForwarder: DEAD_ADDRESS, + // The DisperseForwarder contract on Polygon + bridgeRecipient: DEAD_ADDRESS, +} + export const RBAL: Token = { symbol: "BAL", address: "0x0Aa94D9Db9dA74Bb86A437E28EE4ecf22365843E", @@ -538,5 +549,6 @@ export const tokens = [ mBPT, RmBPT, BAL, + PBAL, RBAL, ] diff --git a/test-fork/emissions/emissions-mainnet-deployment.spec.ts b/test-fork/emissions/emissions-mainnet-deployment.spec.ts index 87bfd28e..9082f5dc 100644 --- a/test-fork/emissions/emissions-mainnet-deployment.spec.ts +++ b/test-fork/emissions/emissions-mainnet-deployment.spec.ts @@ -7,8 +7,8 @@ import { resolveAddress } from "tasks/utils/networkAddressFactory" import { deployBasicForwarder, deployBridgeForwarder, deployEmissionsController, deployRevenueBuyBack } from "tasks/utils/emissions-utils" import { expect } from "chai" import { BN, simpleToExactAmount } from "@utils/math" -import { currentWeekEpoch, increaseTime, increaseTimeTo } from "@utils/time" -import { MAX_UINT256, ONE_WEEK } from "@utils/constants" +import { currentWeekEpoch, increaseTime } from "@utils/time" +import { MAX_UINT256, ONE_HOUR, ONE_WEEK } from "@utils/constants" import { assertBNClose } from "@utils/assertions" import { alUSD, BUSD, Chain, DAI, FEI, GUSD, HBTC, mBTC, MTA, mUSD, RAI, TBTCv2, USDC, WBTC } from "tasks/utils/tokens" import { @@ -18,6 +18,8 @@ import { IERC20__factory, InitializableRewardsDistributionRecipient__factory, IUniswapV3Quoter__factory, + Nexus, + Nexus__factory, RevenueBuyBack, SavingsManager, SavingsManager__factory, @@ -25,11 +27,15 @@ import { import { Account } from "types/common" import { encodeUniswapPath } from "@utils/peripheral/uniswap" import { btcFormatter, usdFormatter } from "tasks/utils/quantity-formatters" +import { keccak256 } from "@ethersproject/keccak256" +import { toUtf8Bytes } from "ethers/lib/utils" const voter1VotingPower = BN.from("44461750008245826445414") const voter2VotingPower = simpleToExactAmount(27527.5) const voter3VotingPower = BN.from("78211723319712171214037") +const keeperKey = keccak256(toUtf8Bytes("Keeper")) + context("Fork test Emissions Controller on mainnet", () => { let ops: Signer let governor: Signer @@ -38,6 +44,7 @@ context("Fork test Emissions Controller on mainnet", () => { let voter3: Account let treasury: Account let emissionsController: EmissionsController + let nexus: Nexus let mta: IERC20 const setRewardsDistribution = async (recipientAddress: string) => { @@ -45,7 +52,7 @@ context("Fork test Emissions Controller on mainnet", () => { await recipient.setRewardsDistribution(emissionsController.address) } - before("reset block number", async () => { + const setup = async () => { await network.provider.request({ method: "hardhat_reset", params: [ @@ -66,10 +73,13 @@ context("Fork test Emissions Controller on mainnet", () => { voter3 = await impersonateAccount("0x530deFD6c816809F54F6CfA6FE873646F6EcF930") // 82,538.415914215331337512 stkBPT treasury = await impersonateAccount("0x3dd46846eed8d147841ae162c8425c08bd8e1b41") + nexus = Nexus__factory.connect(resolveAddress("Nexus"), governor) mta = IERC20__factory.connect(MTA.address, treasury.signer) - }) + } + describe("Deploy contracts", () => { it("Emissions Controller", async () => { + await setup() emissionsController = await deployEmissionsController(ops, hre) expect(await emissionsController.getDialRecipient(0), "dial 0 Staked MTA").to.eq("0x8f2326316eC696F6d023E37A9931c2b2C177a3D7") @@ -145,10 +155,9 @@ context("Fork test Emissions Controller on mainnet", () => { }) }) describe("Set vote weights", () => { - let firstEpoch: BN before(async () => { + await setup() emissionsController = await deployEmissionsController(ops, hre) - firstEpoch = await (await currentWeekEpoch()).add(1) }) it("voter 1", async () => { expect(await emissionsController.callStatic.getVotes(voter1.address), "voter 1 total voting power").to.eq(voter1VotingPower) @@ -205,9 +214,13 @@ context("Fork test Emissions Controller on mainnet", () => { }) describe("calculate rewards", () => { before(async () => { + await setup() + await nexus.proposeModule(keeperKey, resolveAddress("OperationsSigner")) + // increase time to 2 December 2021, Thursday 08:00 UTC - await increaseTimeTo(1638439200) + // await increaseTimeTo(1638439200) emissionsController = await deployEmissionsController(ops, hre) + const visorFinanceDial = await deployBasicForwarder(ops, emissionsController.address, "VisorRouter", hre) await emissionsController.connect(governor).addDial(visorFinanceDial.address, 0, true) @@ -220,12 +233,8 @@ context("Fork test Emissions Controller on mainnet", () => { const fraxBridgeForwarder = await deployBridgeForwarder(ops, hre, fraxBridgeRecipientAddress, emissionsController.address) await emissionsController.connect(governor).addDial(fraxBridgeForwarder.address, 0, true) // Polygon Balancer Pool - const balancerBridgeForwarder = await deployBridgeForwarder( - ops, - hre, - "0x2f2Db75C5276481E2B018Ac03e968af7763Ed118", - emissionsController.address, - ) + const balBridgeRecipientAddress = resolveAddress("BAL", Chain.polygon, "bridgeRecipient") + const balancerBridgeForwarder = await deployBridgeForwarder(ops, hre, balBridgeRecipientAddress, emissionsController.address) await emissionsController.connect(governor).addDial(balancerBridgeForwarder.address, 0, true) // Treasury DAO dial @@ -312,13 +321,17 @@ context("Fork test Emissions Controller on mainnet", () => { weight: 10, // 5% }, ]) + + await increaseTime(ONE_WEEK.add(ONE_HOUR)) + await nexus.acceptProposedModule(keeperKey) }) it("immediately", async () => { const tx = emissionsController.calculateRewards() await expect(tx).to.revertedWith("Must wait for new period") }) it("after 2 weeks", async () => { - await increaseTime(ONE_WEEK.mul(2)) + await increaseTime(ONE_WEEK) + const currentEpochIndex = await currentWeekEpoch() const totalRewardsExpected = await emissionsController.topLineEmission(currentEpochIndex) expect(totalRewardsExpected, "First distribution rewards").to.gt(simpleToExactAmount(165000)).lt(simpleToExactAmount(166000)) @@ -353,7 +366,11 @@ context("Fork test Emissions Controller on mainnet", () => { const bridgeAmount = simpleToExactAmount(10000) before(async () => { + await setup() emissionsController = await deployEmissionsController(ops, hre) + + await nexus.proposeModule(keeperKey, resolveAddress("OperationsSigner")) + const visorFinanceDial = await deployBasicForwarder(ops, emissionsController.address, "VisorRouter", hre) await emissionsController.connect(governor).addDial(visorFinanceDial.address, 0, true) const bridgeRecipient = Wallet.createRandom() @@ -384,6 +401,9 @@ context("Fork test Emissions Controller on mainnet", () => { await setRewardsDistribution(RAI.vault) await setRewardsDistribution(HBTC.vault) await setRewardsDistribution(TBTCv2.vault) + + await increaseTime(ONE_WEEK.add(ONE_HOUR)) + await nexus.acceptProposedModule(keeperKey) }) it("distribute rewards to staking contracts", async () => { const tx = await emissionsController.distributeRewards([0, 1]) @@ -446,9 +466,15 @@ context("Fork test Emissions Controller on mainnet", () => { // 0.04147372e8 WBTC / 1,853e18 MTA = 44685e10 * 1e18 = 4.46e14 * 1e18 = 4.46e32 = 446e30 before(async () => { + await setup() + await nexus.proposeModule(keeperKey, resolveAddress("OperationsSigner")) + emissionsController = await deployEmissionsController(ops, hre) mtaToken = IERC20__factory.connect(MTA.address, ops) revenueBuyBack = await deployRevenueBuyBack(ops, hre, emissionsController.address) + + await increaseTime(ONE_WEEK.add(ONE_HOUR)) + await nexus.acceptProposedModule(keeperKey) }) it("check Uniswap USDC to MTA price", async () => { const uniswapQuoterAddress = resolveAddress("UniswapQuoterV3") diff --git a/test-utils/machines/standardAccounts.ts b/test-utils/machines/standardAccounts.ts index 5f392091..abc8871e 100644 --- a/test-utils/machines/standardAccounts.ts +++ b/test-utils/machines/standardAccounts.ts @@ -48,6 +48,8 @@ export class StandardAccounts { public mockRewardsDistributor: Account + public keeper: Account + public async initAccounts(signers: Signer[]): Promise { this.all = await Promise.all( signers.map(async (s) => ({ @@ -75,6 +77,7 @@ export class StandardAccounts { this.mockRecollateraliser, this.mockMasset, this.mockRewardsDistributor, + this.keeper, ] = this.all return this } diff --git a/test/buy-and-make/revenue-buy-back.spec.ts b/test/buy-and-make/revenue-buy-back.spec.ts index 2a875ac2..ee5a9b68 100644 --- a/test/buy-and-make/revenue-buy-back.spec.ts +++ b/test/buy-and-make/revenue-buy-back.spec.ts @@ -70,6 +70,7 @@ describe("RevenueBuyBack", () => { sa.mockSavingsManager.address, sa.mockInterestValidator.address, ) + await nexus.setKeeper(sa.keeper.address) // Mocked Uniswap V3 uniswap = await new MockUniswapV3__factory(sa.default.signer).deploy() @@ -111,7 +112,7 @@ describe("RevenueBuyBack", () => { emissionController.address, ) // reverse the order to make sure dial id != staking contract id for testing purposes - await revenueBuyBack.initialize(sa.fundManager.address, [1, 0]) + await revenueBuyBack.initialize([1, 0]) // Add config to buy rewards from mAssets await revenueBuyBack @@ -152,7 +153,6 @@ describe("RevenueBuyBack", () => { expect(await revenueBuyBack.EMISSIONS_CONTROLLER(), "Emissions Controller").eq(emissionController.address) }) it("should have storage variables set", async () => { - expect(await revenueBuyBack.keeper(), "Keeper").eq(sa.fundManager.address) expect(await revenueBuyBack.stakingDialIds(0), "Staking Contract 1 dial id").eq(1) expect(await revenueBuyBack.stakingDialIds(1), "Staking Contract 2 dial id").eq(0) expect((await emissionController.dials(0)).recipient, "first dial is first staking contract").to.eq(staking1.address) @@ -195,16 +195,6 @@ describe("RevenueBuyBack", () => { ) await expect(tx).to.revertedWith("Emissions controller is zero") }) - it("Keeper", async () => { - const revBuyBack = await new RevenueBuyBack__factory(sa.default.signer).deploy( - nexus.address, - rewardsToken.address, - uniswap.address, - emissionController.address, - ) - const tx = revBuyBack.initialize(ZERO_ADDRESS, []) - await expect(tx).to.revertedWith("Keeper is zero") - }) }) }) describe("notification of revenue", () => { @@ -269,7 +259,7 @@ describe("RevenueBuyBack", () => { expect(await mUSD.balanceOf(revenueBuyBack.address), "revenueBuyBack's mUSD Bal before").to.eq(musdRevenue) expect(await bAsset1.balanceOf(mUSD.address), "mAsset's bAsset Bal before").to.eq(musdRevenue) - const tx = revenueBuyBack.connect(sa.fundManager.signer).buyBackRewards([mUSD.address]) + const tx = revenueBuyBack.connect(sa.keeper.signer).buyBackRewards([mUSD.address]) const bAsset1Amount = musdRevenue.mul(98).div(100) // Exchange rate = 0.80 MTA/USD = 8 / 18 @@ -283,7 +273,7 @@ describe("RevenueBuyBack", () => { expect(await mBTC.balanceOf(revenueBuyBack.address), "revenueBuyBack's mBTC Bal before").to.eq(mbtcRevenue) expect(await bAsset2.balanceOf(mBTC.address), "mAsset's bAsset Bal before").to.eq(mbtcRevenue.div(1e12)) - const tx = revenueBuyBack.connect(sa.fundManager.signer).buyBackRewards([mBTC.address]) + const tx = revenueBuyBack.connect(sa.keeper.signer).buyBackRewards([mBTC.address]) const bAsset2Amount = mbtcRevenue.mul(98).div(100).div(1e12) // Exchange rate = 50,000 MTA/BTC @@ -294,7 +284,7 @@ describe("RevenueBuyBack", () => { expect(await mBTC.balanceOf(revenueBuyBack.address), "revenueBuyBack's mBTC Bal after").to.eq(0) }) it("should sell mUSD and mBTC for MTA", async () => { - const tx = revenueBuyBack.connect(sa.fundManager.signer).buyBackRewards([mUSD.address, mBTC.address]) + const tx = revenueBuyBack.connect(sa.keeper.signer).buyBackRewards([mUSD.address, mBTC.address]) // const bAsset1Amount = musdRevenue.mul(98).div(100) @@ -314,11 +304,11 @@ describe("RevenueBuyBack", () => { }) describe("should fail when", () => { it("No mAssets", async () => { - const tx = revenueBuyBack.connect(sa.fundManager.signer).buyBackRewards([]) + const tx = revenueBuyBack.connect(sa.keeper.signer).buyBackRewards([]) await expect(tx).to.revertedWith("Invalid args") }) it("Not a mAsset", async () => { - const tx = revenueBuyBack.connect(sa.fundManager.signer).buyBackRewards([rewardsToken.address]) + const tx = revenueBuyBack.connect(sa.keeper.signer).buyBackRewards([rewardsToken.address]) await expect(tx).to.revertedWith("Invalid mAsset") }) it("Not keeper or governor", async () => { @@ -338,7 +328,7 @@ describe("RevenueBuyBack", () => { expect(await rewardsToken.balanceOf(revenueBuyBack.address), "revenue buy back rewards before").to.eq(totalRewards) const rewardsECbefore = await rewardsToken.balanceOf(emissionController.address) - const tx = revenueBuyBack.connect(sa.fundManager.signer).donateRewards() + const tx = revenueBuyBack.connect(sa.keeper.signer).donateRewards() await expect(tx).to.emit(revenueBuyBack, "DonatedRewards").withArgs(totalRewards) await expect(tx).to.emit(emissionController, "DonatedRewards").withArgs(1, totalRewards.div(4)) @@ -354,13 +344,13 @@ describe("RevenueBuyBack", () => { await staking1.setTotalSupply(0) await staking2.setTotalSupply(0) - const tx = revenueBuyBack.connect(sa.fundManager.signer).donateRewards() + const tx = revenueBuyBack.connect(sa.keeper.signer).donateRewards() await expect(tx).to.revertedWith("No voting power") }) it("no rewards to donate", async () => { expect(await rewardsToken.balanceOf(revenueBuyBack.address), "revenue buy back rewards before").to.eq(0) - const tx = revenueBuyBack.connect(sa.fundManager.signer).donateRewards() + const tx = revenueBuyBack.connect(sa.keeper.signer).donateRewards() await expect(tx).to.revertedWith("No rewards to donate") }) }) diff --git a/test/buy-and-make/revenue-forwarder.spec.ts b/test/buy-and-make/revenue-forwarder.spec.ts index 2c00a78a..d8297db0 100644 --- a/test/buy-and-make/revenue-forwarder.spec.ts +++ b/test/buy-and-make/revenue-forwarder.spec.ts @@ -14,7 +14,6 @@ import { } from "types/generated" import { ZERO_ADDRESS } from "@utils/constants" import { Wallet } from "@ethersproject/wallet" -import { Account } from "types/common" describe("RevenueForwarder", () => { let sa: StandardAccounts @@ -22,7 +21,6 @@ describe("RevenueForwarder", () => { let nexus: MockNexus let revenueForwarder: RevenueForwarder let mAsset: MockMasset - let keeper: Account let forwarderAddress: string /* @@ -44,16 +42,11 @@ describe("RevenueForwarder", () => { sa.mockSavingsManager.address, sa.mockInterestValidator.address, ) - keeper = sa.fundManager + await nexus.setKeeper(sa.keeper.address) forwarderAddress = Wallet.createRandom().address // Deploy aRevenueForwarder - revenueForwarder = await new RevenueForwarder__factory(sa.default.signer).deploy( - nexus.address, - mAsset.address, - keeper.address, - forwarderAddress, - ) + revenueForwarder = await new RevenueForwarder__factory(sa.default.signer).deploy(nexus.address, mAsset.address, forwarderAddress) } before(async () => { @@ -68,44 +61,19 @@ describe("RevenueForwarder", () => { it("should have immutable variables set", async () => { expect(await revenueForwarder.nexus(), "Nexus").eq(nexus.address) expect(await revenueForwarder.mAsset(), "mAsset").eq(mAsset.address) - expect(await revenueForwarder.keeper(), "Keeper").eq(keeper.address) expect(await revenueForwarder.forwarder(), "Forwarder").eq(forwarderAddress) }) describe("it should fail if zero", () => { it("nexus", async () => { - const tx = new RevenueForwarder__factory(sa.default.signer).deploy( - ZERO_ADDRESS, - mAsset.address, - keeper.address, - forwarderAddress, - ) + const tx = new RevenueForwarder__factory(sa.default.signer).deploy(ZERO_ADDRESS, mAsset.address, forwarderAddress) await expect(tx).to.revertedWith("Nexus address is zero") }) it("mAsset", async () => { - const tx = new RevenueForwarder__factory(sa.default.signer).deploy( - nexus.address, - ZERO_ADDRESS, - keeper.address, - forwarderAddress, - ) + const tx = new RevenueForwarder__factory(sa.default.signer).deploy(nexus.address, ZERO_ADDRESS, forwarderAddress) await expect(tx).to.revertedWith("mAsset is zero") }) - it("Keeper", async () => { - const tx = new RevenueForwarder__factory(sa.default.signer).deploy( - nexus.address, - mAsset.address, - ZERO_ADDRESS, - forwarderAddress, - ) - await expect(tx).to.revertedWith("Keeper is zero") - }) it("Forwarder", async () => { - const tx = new RevenueForwarder__factory(sa.default.signer).deploy( - nexus.address, - mAsset.address, - keeper.address, - ZERO_ADDRESS, - ) + const tx = new RevenueForwarder__factory(sa.default.signer).deploy(nexus.address, mAsset.address, ZERO_ADDRESS) await expect(tx).to.revertedWith("Forwarder is zero") }) }) @@ -162,7 +130,7 @@ describe("RevenueForwarder", () => { expect(await mAsset.balanceOf(revenueForwarder.address), "revenue forwarder's mAsset bal before").to.eq(notificationAmount) expect(await mAsset.balanceOf(forwarderAddress), "forwarder's mAsset bal before").to.eq(0) - const tx = await revenueForwarder.connect(keeper.signer).forward() + const tx = await revenueForwarder.connect(sa.keeper.signer).forward() await expect(tx).to.emit(revenueForwarder, "Withdrawn").withArgs(notificationAmount) expect(await mAsset.balanceOf(revenueForwarder.address), "revenue forwarder's mAsset bal after").to.eq(0) @@ -180,11 +148,11 @@ describe("RevenueForwarder", () => { }) it("should forward with no rewards balance", async () => { // Forward whatever balance it currently has - await revenueForwarder.connect(keeper.signer).forward() + await revenueForwarder.connect(sa.keeper.signer).forward() expect(await mAsset.balanceOf(revenueForwarder.address), "revenue forwarder's mAsset bal before").to.eq(0) - const tx = await revenueForwarder.connect(keeper.signer).forward() + const tx = await revenueForwarder.connect(sa.keeper.signer).forward() await expect(tx).to.not.emit(revenueForwarder, "Withdrawn") expect(await mAsset.balanceOf(revenueForwarder.address), "revenue forwarder's mAsset bal after").to.eq(0) @@ -206,7 +174,7 @@ describe("RevenueForwarder", () => { expect(await revenueForwarder.forwarder(), "forwarder after").to.eq(newForwarderAddress) }) it("keeper should fail to set new forwarder", async () => { - const tx = revenueForwarder.connect(keeper.signer).setConfig(newForwarderAddress) + const tx = revenueForwarder.connect(sa.keeper.signer).setConfig(newForwarderAddress) await expect(tx).to.revertedWith("Only governor can execute") }) diff --git a/test/emissions/emission-controller.spec.ts b/test/emissions/emission-controller.spec.ts index 177eaaec..02bbaf71 100644 --- a/test/emissions/emission-controller.spec.ts +++ b/test/emissions/emission-controller.spec.ts @@ -19,6 +19,7 @@ import { } from "types/generated" import { currentWeekEpoch, increaseTime, getTimestamp, increaseTimeTo, startWeek, weekEpoch } from "@utils/time" import { Account } from "types/common" +import { keccak256, toUtf8Bytes } from "ethers/lib/utils" const defaultConfig = { A: -166000000000000, @@ -36,12 +37,12 @@ interface VoteHistoryExpectation { lastEpoch: number } interface DialData { - disabled: boolean - notify: boolean - cap: number - balance: BN - recipient: string - voteHistory: { votes: BN; epoch: number }[] + disabled: boolean + notify: boolean + cap: number + balance: BN + recipient: string + voteHistory: { votes: BN; epoch: number }[] } /** @@ -136,10 +137,7 @@ const expectTopLineEmissionForEpoch = (emissionsController: EmissionsController, const expectedEmissionAmount = await nextRewardAmount(emissionsController, deltaEpoch) expect(emissionForEpoch).eq(expectedEmissionAmount) } -const snapDial = async ( - emissionsController: EmissionsController, - dialId: number, -): Promise => { +const snapDial = async (emissionsController: EmissionsController, dialId: number): Promise => { const dialData = await emissionsController.dials(dialId) const voteHistory = await emissionsController.getDialVoteHistory(dialId) return { @@ -214,6 +212,8 @@ describe("EmissionsController", async () => { const accounts = await ethers.getSigners() sa = await new StandardAccounts().initAccounts(accounts) + console.log(`Keeper ${keccak256(toUtf8Bytes("Keeper"))}`) + voter1 = sa.dummy1 voter2 = sa.dummy2 voter3 = sa.dummy3 @@ -719,9 +719,9 @@ describe("EmissionsController", async () => { await increaseTime(ONE_WEEK) // Expect initial vote with no weight - const dialsVoteHistory = [ { dialId: 0, votesNo: 1, lastVote: 0, lastEpoch: startEpoch} ] + const dialsVoteHistory = [{ dialId: 0, votesNo: 1, lastVote: 0, lastEpoch: startEpoch }] await expectDialVotesHistoryForDials(emissionsController, dialsVoteHistory) - + const tx = await emissionsController.calculateRewards() await expect(tx).to.emit(emissionsController, "PeriodRewards").withArgs([0, 0, 0]) @@ -765,12 +765,14 @@ describe("EmissionsController", async () => { await emissionsController.connect(voter1.signer).setVoterDialWeights([{ dialId: 0, weight: 200 }]) // Expect dial 1 vote history updated with 300 votes (dialId = n-1) - const dialVoteHistory = [{ - dialId: 0, - votesNo: 1, - lastVote: VOTERS["1"].votes, - lastEpoch: startEpoch, - }] + const dialVoteHistory = [ + { + dialId: 0, + votesNo: 1, + lastVote: VOTERS["1"].votes, + lastEpoch: startEpoch, + }, + ] await expectDialVotesHistoryForDials(emissionsController, dialVoteHistory) await increaseTime(ONE_WEEK) @@ -1394,8 +1396,8 @@ describe("EmissionsController", async () => { it("disabled should not receive any distribution", async () => { // Given that dial 1 is disabled, and dial 2 is enabled // and voter 1 gives all its votes to dial 1, and voter 2 gives all its votes to dial 2, - // and dial 3 does not have any vote weight - const dialBefore = []; + // and dial 3 does not have any vote weight + const dialBefore = [] let tx = await emissionsController.connect(sa.governor.signer).updateDial(0, true) dialBefore[0] = await snapDial(emissionsController, 0) dialBefore[1] = await snapDial(emissionsController, 1) @@ -1407,16 +1409,15 @@ describe("EmissionsController", async () => { ] await expectDialVotesHistoryForDials(emissionsController, dialVoteHistory) - // When it calculates rewards + // When it calculates rewards await increaseTime(ONE_WEEK) const nextEpochEmission = await nextRewardAmount(emissionsController) tx = await emissionsController.calculateRewards() - const dialAfter = []; + const dialAfter = [] dialAfter[0] = await snapDial(emissionsController, 0) dialAfter[1] = await snapDial(emissionsController, 1) - // Then disabled dials should not receive any distribution await expect(tx).to.emit(emissionsController, "PeriodRewards").withArgs([0, nextEpochEmission, 0]) expect((await emissionsController.dials(0)).balance, "dial 1 balance after").to.eq(0) @@ -1430,9 +1431,9 @@ describe("EmissionsController", async () => { it("disabled then re-enabled it should receive distribution", async () => { // Given a dial 1 is enabled, and dial 2 is enabled // and voter 1 gives all its votes to dial 1, and voter 2 gives all its votes to dial 2, - // and dial 3 does not have any vote weight - const dialBefore:Array = []; - const dialAfter:Array = []; + // and dial 3 does not have any vote weight + const dialBefore: Array = [] + const dialAfter: Array = [] let tx = await emissionsController.connect(sa.governor.signer).updateDial(0, true) dialBefore[0] = await snapDial(emissionsController, 0) @@ -1456,7 +1457,7 @@ describe("EmissionsController", async () => { // Then no new votes should be cast for disabled dials expect(dialBefore[0].voteHistory.length, "dial 1 vote history should not change").to.eq(dialAfter[0].voteHistory.length) - // When the dial is re-enabled and it calculates rewards + // When the dial is re-enabled and it calculates rewards tx = await emissionsController.connect(sa.governor.signer).updateDial(0, false) await expect(tx).to.emit(emissionsController, "UpdatedDial").withArgs(0, false) @@ -1479,21 +1480,24 @@ describe("EmissionsController", async () => { // New votes should be cast for enabled dials expect(dialBefore[0].voteHistory.length + 1, "dial 1 vote history should increase").to.eq(dialAfter[0].voteHistory.length) - expect(dialBefore[0].voteHistory.slice(-1)[0].votes, "dial 1 vote weight should not change").to.eq(dialAfter[0].voteHistory.slice(-1)[0].votes) + expect(dialBefore[0].voteHistory.slice(-1)[0].votes, "dial 1 vote weight should not change").to.eq( + dialAfter[0].voteHistory.slice(-1)[0].votes, + ) expect(dialBefore[1].voteHistory.length + 2, "dial 2 vote history should increase").to.eq(dialAfter[1].voteHistory.length) - expect(dialBefore[1].voteHistory.slice(-1)[0].votes, "dial 2 vote weight should not change").to.eq(dialAfter[1].voteHistory.slice(-1)[0].votes) - + expect(dialBefore[1].voteHistory.slice(-1)[0].votes, "dial 2 vote weight should not change").to.eq( + dialAfter[1].voteHistory.slice(-1)[0].votes, + ) }) // TODO after a new dial was added that was not in previous distributions [DONE] it("added that was not in previous distributions", async () => { // --- Given --- // that dial 1,2 and 3 are enabled - // and voter 1 gives all its votes to dial 1, and voter 2 gives all its votes to dial 2, and dial 3 does not have any vote weight + // and voter 1 gives all its votes to dial 1, and voter 2 gives all its votes to dial 2, and dial 3 does not have any vote weight - const dialBefore:Array = []; - const dialAfter:Array = []; - const adjustedDials:BN[][] = [[]] + const dialBefore: Array = [] + const dialAfter: Array = [] + const adjustedDials: BN[][] = [[]] dialBefore[0] = await snapDial(emissionsController, 0) dialBefore[1] = await snapDial(emissionsController, 1) @@ -1511,7 +1515,6 @@ describe("EmissionsController", async () => { let nextEpochEmission = await nextRewardAmount(emissionsController) let tx = await emissionsController.calculateRewards() - dialAfter[0] = await snapDial(emissionsController, 0) dialAfter[1] = await snapDial(emissionsController, 1) @@ -1532,23 +1535,26 @@ describe("EmissionsController", async () => { // -- When -- // it adds a new dial and calculates the distribution - const newDial = await new MockRewardsDistributionRecipient__factory(sa.default.signer).deploy(rewardToken.address, DEAD_ADDRESS) + const newDial = await new MockRewardsDistributionRecipient__factory(sa.default.signer).deploy( + rewardToken.address, + DEAD_ADDRESS, + ) tx = await emissionsController.connect(sa.governor.signer).addDial(newDial.address, 0, true) - await expect(tx).to.emit(emissionsController, "AddedDial").withArgs(3, newDial.address) + await expect(tx).to.emit(emissionsController, "AddedDial").withArgs(3, newDial.address) - // Assign voters 3 weight to new dial - await emissionsController.connect(voter3.signer).setVoterDialWeights([{ dialId: 3, weight: 200 }]) + // Assign voters 3 weight to new dial + await emissionsController.connect(voter3.signer).setVoterDialWeights([{ dialId: 3, weight: 200 }]) dialBefore[3] = await snapDial(emissionsController, 3) // calculates distribution await increaseTime(ONE_WEEK) - nextEpochEmission = await nextRewardAmount(emissionsController) - tx = await emissionsController.calculateRewards() + nextEpochEmission = await nextRewardAmount(emissionsController) + tx = await emissionsController.calculateRewards() - dialAfter[0] = await snapDial(emissionsController, 0) - dialAfter[1] = await snapDial(emissionsController, 1) - dialAfter[3] = await snapDial(emissionsController, 3) + dialAfter[0] = await snapDial(emissionsController, 0) + dialAfter[1] = await snapDial(emissionsController, 1) + dialAfter[3] = await snapDial(emissionsController, 3) // -- Then -- // the new dial should receive emissions after calculating rewards @@ -1558,11 +1564,13 @@ describe("EmissionsController", async () => { adjustedDials[1][1] = nextEpochEmission.div(2) // Voter 3 has 300 of the 1200 votes (2/5) adjustedDials[3][0] = BN.from(0) - adjustedDials[3][1] = nextEpochEmission.div(4) + adjustedDials[3][1] = nextEpochEmission.div(4) // Then disabled dials should not receive any distribution - - await expect(tx).to.emit(emissionsController, "PeriodRewards").withArgs([adjustedDials[0][1], adjustedDials[1][1], 0, adjustedDials[3][1]]) - const sum = (a:BN, b:BN) => a.add(b); + + await expect(tx) + .to.emit(emissionsController, "PeriodRewards") + .withArgs([adjustedDials[0][1], adjustedDials[1][1], 0, adjustedDials[3][1]]) + const sum = (a: BN, b: BN) => a.add(b) expect((await emissionsController.dials(0)).balance, "dial 1 balance after").to.eq(adjustedDials[0].reduce(sum)) expect((await emissionsController.dials(1)).balance, "dial 2 balance after").to.eq(adjustedDials[1].reduce(sum)) @@ -1570,7 +1578,9 @@ describe("EmissionsController", async () => { expect((await emissionsController.dials(3)).balance, "dial new balance after").to.eq(adjustedDials[3].reduce(sum)) // New votes should be cast for new dial expect(dialBefore[3].voteHistory.length + 1, "dial new vote history should increase").to.eq(dialAfter[3].voteHistory.length) - expect(dialBefore[3].voteHistory.slice(-1)[0].votes, "dial 1 vote weight should not change").to.eq(dialAfter[3].voteHistory.slice(-1)[0].votes) + expect(dialBefore[3].voteHistory.slice(-1)[0].votes, "dial 1 vote weight should not change").to.eq( + dialAfter[3].voteHistory.slice(-1)[0].votes, + ) }) }) // TODO after a new staking contract was added that was not in previous distributions @@ -2342,4 +2352,4 @@ describe("EmissionsController", async () => { }) }) }) -}) \ No newline at end of file +}) From eb7b9aa2a2bc6176444f4c952c311c878ac25afa Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Fri, 3 Dec 2021 18:16:18 +1100 Subject: [PATCH 2/6] chore: Added sequence diagram for emissions to Balancer Pool on Polygon --- contracts/emissions/README.md | 4 ++++ docs/emissions/polygonBridge_balancer.png | Bin 0 -> 149733 bytes 2 files changed, 4 insertions(+) create mode 100644 docs/emissions/polygonBridge_balancer.png diff --git a/contracts/emissions/README.md b/contracts/emissions/README.md index e0f6bb18..9add6eb1 100644 --- a/contracts/emissions/README.md +++ b/contracts/emissions/README.md @@ -130,6 +130,10 @@ It’s possible the MTA rewards can be calculated but not transferred. Each new ![Polygon Bridge FRAX](../../docs/emissions/polygonBridge_frax.png) +### Distribution to Balancer Pool liquidity providers on Polygon + +![Polygon Bridge Balancer](../../docs/emissions/polygonBridge_balancer.png) + ### MTA Buy Back for Stakers ![Buy Back For Stakers](../../docs/emissions/buyBackForStakers.png) diff --git a/docs/emissions/polygonBridge_balancer.png b/docs/emissions/polygonBridge_balancer.png new file mode 100644 index 0000000000000000000000000000000000000000..45f4122b41a607464f12b0945f3e79254dd7410e GIT binary patch literal 149733 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

O!~sq?gm_$iEZ+x1fpmb6TQKH$qIESFC(^z zFVsRiAk+5A=T7hdz;H?l)Cf`|eP=_4Qx|}w!w{)l;7F(uNaOAvq#WXYOB-&PgTp4O z*kY{trI(j z0hF+451C}u%|JEB2kj4(cC0l3DlMO6YQ(e~fr4TZIPj_Y)43(KEVksHOh<5Ijgo>y z;is`w)e!d_*wcN4gioq=Kf>+s?afbiNo6+bG8F2b-|MqTIWM9=g1MOQonGheE9_@R zcd1*&fL>Mv&HuhQ0?n^7YHYyR;Zc|V^Py(f@u`d1Nc7Yc@PK_MKyshW!MDzdp4#Ts znkqMRt8X9$y53`n8x&tdsR0C|MK-C)z>6tE2sL8gb;zyyj)1KMj?hnNbBHrw;Rx8G zEbQG!ZY+$2BJ(=Xv-a^d3Xmnaue_q9rdEw(1D?c%&BQ9mm4=jQ`3^>!yyJgb%NmiBn~ zZUzn&O`Ytl*r15Y7b*xlJx@m(A%0DAwX+ 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 z z7{?OK6C4YWXn>yx+)r8XWTrM49estvn%XLWik%$sK==(a5X|TQ=YTF9tZMAyeO!=0 zx3sDuy{`r$R`L84=>zKkQd%4zp#W4jpm#7|#SEua*T(VH!>0A7X*bOKg5P3pjp1`S zK>(|9AWI=zvx)>L7gg0>etx~K#NeL&iJt@{0YlMd2kUqJNo9O71IAn+9v-cK84Alj z-#8+`*J$4P+VVed3Uz`2DtD`X(c&T}j-ou4!j}AHORHg#*GX&Y<^J+{tF6G z{Y}tMVM?MD_&0*p3SCKiSi`f!%fcJOyPa8FgWE{K)YdToG%EU%;+QM2ak^u)Mno@| z-#OVZXz2-3GID_#GNVUQbIdFmk#Jx1wlOt<_ACrDyEh-Q!Py=%)@{TkB8oPu4;|}1 z%HEQFDf>Y-8Q2%h|7?~t2Z-=YvxV(SWlsZOE&vKO!0l|da9_Om26}t@FcVRX?f@oV z^dM~5k;U*N%m1$_qifs$C`p@6nI1v^i9Yeb;Oyhy!5&v*Kl{sm%^;OYNH0nJr4@7L z-mT51;7VDD6>T=jU?{Ly9$2RCny_$E;%Hd;>S&Qi4%UBW zm1}&`!|Pf0UwKm3`#qMF`CE9{9R(E!nkV|9k~E;EJIxpeCL%J_SKK{P%=`WO(61)* z+cQvZ9-b>#9VaVoK~El5JiHT35J#%yYfxlJ!QONu0q}hH4bDmyejo65&wWhSLc1+f z{bvE54k7fmuYv_AU> zob^Cd+=G??qba~!1zif7hg^2?#n#V9Oe-n}celwvQ{<@Obb)hj0pPNOtlLq=8kdm> zM#CNy5x+w%ppczD-W=Lp9_aduznA!fa3$vtR{N6E(~pC>u{}=v9aI2R!aM+|q8y#S zw8NS`f@I5peBRBrv&oA_=NlxX1YaQxZoM2tVO@bznnnp!FCvC{CxLttt=G~UoI69C{-Q#FD6zY zO0#%jz}#C1uhRRtdvY?ko=Ah_yICL6bwi@aC1L0IEwv_dFTQ^?5g6%jSkGgW3_1JF zzcL#uU>>wsy`*c0TZmH2_sbLi_IfqNuHa8uo|fNq+lADX3W$w0ha>-Me~%s*H2^C; z?&091A0G$(m8)1foM?~xf6?9*ZDnhsw~HcM2YvGpU7V=3ChB%HvDk_H6?a(dHRpf7 zI9L_Re_jVTQEc6pVi`ALcET^a_mdavm^1RQ?(Mb7oj#@BTZBrh=dQn1|9b$JvI~p_ zwuReahnf8+sfI)kXv!#L-bJAi`~I{t#(}S@$ zpQrzS-okjZltt#+=}wnG#Z7R7W95!~<>8t##A)>QR`tpPi*YIIrJ;k_IRBV^V1M^a zLZjC%*CA(EMwu8#xf)L0dB^*o8A5v`BRwhM=7%jY_r^Zv0b2!gc_dH1HcPm)2y*qJ z#2TLE9(MoM#n@Muf8NBET*olmFaHC4&yK%Fi0$lCv1`2NyyeuCSHNe%1zuw}&CorZ zIHB`>+&HnD+Hv8Ub<1{1fUT4BR|5PZ*LHeA{4cWzm^fAw zprtlws+N_NwY9Z{XD(wiV6zqu2`2))g@5)ruvY)>^J~D?#@ufcH|YWpgU72KpMhe5 zj~_oC*cVoox*T?$`=bYc_Xw7&BV-;>fNx&;D@*`5obUEW^FQ9vKi^5(jJ5fhf&gQB>R7SSc(Pr)g86P; zD>*QUU*7zm|I`Tn?=MFp!TtW%=R(Y{|Nr;Fr3>uf5Y^cSsk3h|ZzA?uS~%~Oj@SPK D#=_Lx literal 0 HcmV?d00001 From 314f677127a477b290f833b74926d91782e83288 Mon Sep 17 00:00:00 2001 From: doncesarts Date: Fri, 3 Dec 2021 15:13:35 +0000 Subject: [PATCH 3/6] feat: adds VotiumBribeForwarder --- contracts/emissions/VotiumBribeForwarder.sol | 65 ++++++++++++++++++++ contracts/interfaces/IVotiumBribe.sol | 8 +++ tasks/deployEmissionsController.ts | 5 ++ tasks/utils/emissions-utils.ts | 31 ++++++++-- 4 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 contracts/emissions/VotiumBribeForwarder.sol create mode 100644 contracts/interfaces/IVotiumBribe.sol diff --git a/contracts/emissions/VotiumBribeForwarder.sol b/contracts/emissions/VotiumBribeForwarder.sol new file mode 100644 index 00000000..6c059278 --- /dev/null +++ b/contracts/emissions/VotiumBribeForwarder.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.6; + +import { IERC20, SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { IVotiumBribe } from "../interfaces/IVotiumBribe.sol"; +import { ImmutableModule } from "../shared/ImmutableModule.sol"; + +/** + * @title VotiumBribeForwarder + * @author mStable + * @notice Transfers reward tokens to a list of off-chain calculated recipients and amounts. + * @dev VotiumBribe contract on Mainnet, Polygon, Fantom: 0x19bbc3463dd8d07f55438014b021fb457ebd4595 + * @dev VERSION: 1.0 + * DATE: 2021-11-03 + */ +contract VotiumBribeForwarder is ImmutableModule { + using SafeERC20 for IERC20; + + /// @notice Rewards token that is to be deposit. + IERC20 public immutable REWARDS_TOKEN; + /// @notice Token Disperser contract. eg 0x19bbc3463dd8d07f55438014b021fb457ebd4595 + IVotiumBribe public immutable VOTIUM_BRIBE; + /// @notice Votium brive proposal. + bytes32 public immutable PROPOSAL; + /// @notice Votium brive deposit choice index. + uint256 public choiceIndex + + /** + * @param _rewardsToken Bridged rewards token on the Polygon chain. + * @param _votiumBribe Token votium bribe contract. + * @param _proposal The proposal to bribe. + */ + constructor(address _nexus, address _rewardsToken, address _votiumBribe, bytes32 _proposal) + ImmutableModule(_nexus) { + require(_rewardsToken != address(0), "Invalid Rewards token"); + require(_votiumBribe != address(0), "Invalid VotiumBribe contract"); + REWARDS_TOKEN = IERC20(_rewardsToken); + VOTIUM_BRIBE = IVotiumBribe(_votiumBribe); + PROPOSAL = _proposal; + } + + + /** + * @notice Deposits a bribe into Votium, choiceIndex must be set previously. + * @param amount amount of reward token to deposit including decimal places. + */ + function disperseToken(uint256 amount) external onlyKeeperOrGovernor { + require(amount != 0, "Invalid amount"); + + uint256 rewardBal = REWARDS_TOKEN.balanceOf(address(this)); + require(rewardBal >= amount, "Insufficient rewards"); + // Approve only the amount to be bribe. Any more and the funds in this contract can be stolen + // using the depositBribe function on the VotiumBribe contract. + REWARDS_TOKEN.safeApprove(address(VOTIUM_BRIBE), total); + VOTIUM_BRIBE.depositBribe(address(REWARDS_TOKEN), total, PROPOSAL, choiceIndex); + } + + /** + * @notice Updates the choice index used for the bribe. + * @param _choiceIndex the bribe choice index + */ + function updateChoiceIndex(uint256 _choiceIndex) public onlyKeeperOrGovernor { + choiceIndex = _feeAddress; + } +} diff --git a/contracts/interfaces/IVotiumBribe.sol b/contracts/interfaces/IVotiumBribe.sol new file mode 100644 index 00000000..1dcf9dee --- /dev/null +++ b/contracts/interfaces/IVotiumBribe.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.6; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +interface IVotiumBribe { + function depositBribe(address _token, uint256 _amount, bytes32 _proposal, uint256 _choiceIndex) external ; +} diff --git a/tasks/deployEmissionsController.ts b/tasks/deployEmissionsController.ts index 3c794e62..0574430c 100644 --- a/tasks/deployEmissionsController.ts +++ b/tasks/deployEmissionsController.ts @@ -8,6 +8,7 @@ import { deployBasicForwarder, deployBridgeForwarder, deployDisperseForwarder, + deployVotiumBribeForwarder, deployEmissionsController, deployL2BridgeRecipients, deployL2EmissionsController, @@ -30,6 +31,10 @@ task("deploy-emissions-polly", "Deploys L2EmissionsController and L2 Bridge Reci const disperseForwarder = await deployDisperseForwarder(signer, hre) console.log(`Set PBAL bridgeRecipient to ${disperseForwarder.address}`) + + const votiumBribeForwarder = await deployVotiumBribeForwarder(signer, hre) + console.log(`Set ? bridgeRecipient to ${votiumBribeForwarder.address}`) + }) task("deploy-emissions") diff --git a/tasks/utils/emissions-utils.ts b/tasks/utils/emissions-utils.ts index 913d0972..c37dc593 100644 --- a/tasks/utils/emissions-utils.ts +++ b/tasks/utils/emissions-utils.ts @@ -8,6 +8,8 @@ import { BridgeForwarder__factory, DisperseForwarder, DisperseForwarder__factory, + VotiumBribeForwarder, + VotiumBribeForwarder__factory, EmissionsController, EmissionsController__factory, L2BridgeRecipient, @@ -188,12 +190,13 @@ export const deployL2BridgeRecipients = async ( } export const deployDisperseForwarder = async (signer: Signer, hre: HardhatRuntimeEnvironment): Promise => { + const chain = getChain(hre) + const nexusAddress = resolveAddress("Nexus", chain) + const disperseAddress = resolveAddress("Disperse", chain) const mtaAddress = MTA.address - const constructorArguments = [mtaAddress] + const constructorArguments = [nexusAddress, disperseAddress, mtaAddress] - const disperseForwarder = await deployContract(new DisperseForwarder__factory(signer), "DisperseForwarder", [ - mtaAddress, - ]) + const disperseForwarder = await deployContract(new DisperseForwarder__factory(signer), "DisperseForwarder", constructorArguments) await verifyEtherscan(hre, { address: disperseForwarder.address, @@ -204,6 +207,26 @@ export const deployDisperseForwarder = async (signer: Signer, hre: HardhatRuntim return disperseForwarder } +export const deployVotiumBribeForwarder = async (signer: Signer, hre: HardhatRuntimeEnvironment): Promise => { + + const chain = getChain(hre) + const nexusAddress = resolveAddress("Nexus", chain) + const votiumBribeAddress = resolveAddress("VotiumBribe", chain) + const mtaAddress = MTA.address + const votiumBribeProposal = "TODO-SHOULD-BE-CONFIGURABLE" + const constructorArguments = [nexusAddress, mtaAddress, votiumBribeAddress, votiumBribeProposal] + + const votiumBribeForwarder = await deployContract(new VotiumBribeForwarder__factory(signer), "VotiumBribeForwarder", constructorArguments) + + await verifyEtherscan(hre, { + address: votiumBribeForwarder.address, + constructorArguments, + contract: "contracts/emissions/VotiumBribeForwarder.sol:VotiumBribeForwarder", + }) + + return votiumBribeForwarder +} + export const deployBridgeForwarder = async ( signer: Signer, hre: HardhatRuntimeEnvironment, From 78170f97b34620ea5df16100cbf53cd3f2a05ba3 Mon Sep 17 00:00:00 2001 From: doncesarts Date: Fri, 3 Dec 2021 15:24:57 +0000 Subject: [PATCH 4/6] chore: fixes solhit issues on VotiumBribe --- contracts/emissions/VotiumBribeForwarder.sol | 15 +++++++++------ tasks/utils/emissions-utils.ts | 8 ++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/contracts/emissions/VotiumBribeForwarder.sol b/contracts/emissions/VotiumBribeForwarder.sol index 6c059278..021b73ed 100644 --- a/contracts/emissions/VotiumBribeForwarder.sol +++ b/contracts/emissions/VotiumBribeForwarder.sol @@ -16,14 +16,17 @@ import { ImmutableModule } from "../shared/ImmutableModule.sol"; contract VotiumBribeForwarder is ImmutableModule { using SafeERC20 for IERC20; - /// @notice Rewards token that is to be deposit. + /// @notice Rewards token that is to be deposit. + // solhint-disable-next-line var-name-mixedcase IERC20 public immutable REWARDS_TOKEN; - /// @notice Token Disperser contract. eg 0x19bbc3463dd8d07f55438014b021fb457ebd4595 + /// @notice Token VotiumBribe contract. eg 0x19bbc3463dd8d07f55438014b021fb457ebd4595 + // solhint-disable-next-line var-name-mixedcase IVotiumBribe public immutable VOTIUM_BRIBE; /// @notice Votium brive proposal. + // solhint-disable-next-line var-name-mixedcase bytes32 public immutable PROPOSAL; /// @notice Votium brive deposit choice index. - uint256 public choiceIndex + uint256 public choiceIndex; /** * @param _rewardsToken Bridged rewards token on the Polygon chain. @@ -51,8 +54,8 @@ contract VotiumBribeForwarder is ImmutableModule { require(rewardBal >= amount, "Insufficient rewards"); // Approve only the amount to be bribe. Any more and the funds in this contract can be stolen // using the depositBribe function on the VotiumBribe contract. - REWARDS_TOKEN.safeApprove(address(VOTIUM_BRIBE), total); - VOTIUM_BRIBE.depositBribe(address(REWARDS_TOKEN), total, PROPOSAL, choiceIndex); + REWARDS_TOKEN.safeApprove(address(VOTIUM_BRIBE), amount); + VOTIUM_BRIBE.depositBribe(address(REWARDS_TOKEN), amount, PROPOSAL, choiceIndex); } /** @@ -60,6 +63,6 @@ contract VotiumBribeForwarder is ImmutableModule { * @param _choiceIndex the bribe choice index */ function updateChoiceIndex(uint256 _choiceIndex) public onlyKeeperOrGovernor { - choiceIndex = _feeAddress; + choiceIndex = _choiceIndex; } } diff --git a/tasks/utils/emissions-utils.ts b/tasks/utils/emissions-utils.ts index c37dc593..69e9b7d9 100644 --- a/tasks/utils/emissions-utils.ts +++ b/tasks/utils/emissions-utils.ts @@ -243,16 +243,16 @@ export const deployBridgeForwarder = async ( const emissionsControllerAddress = _emissionsControllerAddress || resolveAddress("EmissionsController", chain) const constructorArguments = [nexusAddress, mtaAddress, tokenBridgeAddress, rootChainManagerAddress, bridgeRecipientAddress] - const bridgeForrwarderImpl = await deployContract( + const bridgeForwarderImpl = await deployContract( new BridgeForwarder__factory(signer), "mUSD Vault Bridge Forwarder", constructorArguments, ) // Deploy proxy and initialize - const initializeData = bridgeForrwarderImpl.interface.encodeFunctionData("initialize", [emissionsControllerAddress]) + const initializeData = bridgeForwarderImpl.interface.encodeFunctionData("initialize", [emissionsControllerAddress]) const proxy = await deployContract(new AssetProxy__factory(signer), "AssetProxy", [ - bridgeForrwarderImpl.address, + bridgeForwarderImpl.address, proxyAdminAddress, initializeData, ]) @@ -266,7 +266,7 @@ export const deployBridgeForwarder = async ( await sleep(10000) await verifyEtherscan(hre, { - address: bridgeForrwarderImpl.address, + address: bridgeForwarderImpl.address, constructorArguments, contract: "contracts/emissions/BridgeForwarder.sol:BridgeForwarder", }) From 8c30dba739c2f457dd236ed03e0cb51915435b47 Mon Sep 17 00:00:00 2001 From: doncesarts Date: Fri, 3 Dec 2021 15:47:36 +0000 Subject: [PATCH 5/6] refactor: moves VotiumBribe proposal from constructor to fn --- contracts/emissions/VotiumBribeForwarder.sol | 12 ++++-------- tasks/utils/emissions-utils.ts | 3 +-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/contracts/emissions/VotiumBribeForwarder.sol b/contracts/emissions/VotiumBribeForwarder.sol index 021b73ed..5bd76e6b 100644 --- a/contracts/emissions/VotiumBribeForwarder.sol +++ b/contracts/emissions/VotiumBribeForwarder.sol @@ -22,32 +22,28 @@ contract VotiumBribeForwarder is ImmutableModule { /// @notice Token VotiumBribe contract. eg 0x19bbc3463dd8d07f55438014b021fb457ebd4595 // solhint-disable-next-line var-name-mixedcase IVotiumBribe public immutable VOTIUM_BRIBE; - /// @notice Votium brive proposal. - // solhint-disable-next-line var-name-mixedcase - bytes32 public immutable PROPOSAL; /// @notice Votium brive deposit choice index. uint256 public choiceIndex; /** * @param _rewardsToken Bridged rewards token on the Polygon chain. * @param _votiumBribe Token votium bribe contract. - * @param _proposal The proposal to bribe. */ - constructor(address _nexus, address _rewardsToken, address _votiumBribe, bytes32 _proposal) + constructor(address _nexus, address _rewardsToken, address _votiumBribe) ImmutableModule(_nexus) { require(_rewardsToken != address(0), "Invalid Rewards token"); require(_votiumBribe != address(0), "Invalid VotiumBribe contract"); REWARDS_TOKEN = IERC20(_rewardsToken); VOTIUM_BRIBE = IVotiumBribe(_votiumBribe); - PROPOSAL = _proposal; } /** * @notice Deposits a bribe into Votium, choiceIndex must be set previously. * @param amount amount of reward token to deposit including decimal places. + * @param proposal votium brive proposal */ - function disperseToken(uint256 amount) external onlyKeeperOrGovernor { + function depositBribe(uint256 amount, bytes32 proposal) external onlyKeeperOrGovernor { require(amount != 0, "Invalid amount"); uint256 rewardBal = REWARDS_TOKEN.balanceOf(address(this)); @@ -55,7 +51,7 @@ contract VotiumBribeForwarder is ImmutableModule { // Approve only the amount to be bribe. Any more and the funds in this contract can be stolen // using the depositBribe function on the VotiumBribe contract. REWARDS_TOKEN.safeApprove(address(VOTIUM_BRIBE), amount); - VOTIUM_BRIBE.depositBribe(address(REWARDS_TOKEN), amount, PROPOSAL, choiceIndex); + VOTIUM_BRIBE.depositBribe(address(REWARDS_TOKEN), amount, proposal, choiceIndex); } /** diff --git a/tasks/utils/emissions-utils.ts b/tasks/utils/emissions-utils.ts index 69e9b7d9..ae7235ae 100644 --- a/tasks/utils/emissions-utils.ts +++ b/tasks/utils/emissions-utils.ts @@ -213,8 +213,7 @@ export const deployVotiumBribeForwarder = async (signer: Signer, hre: HardhatRun const nexusAddress = resolveAddress("Nexus", chain) const votiumBribeAddress = resolveAddress("VotiumBribe", chain) const mtaAddress = MTA.address - const votiumBribeProposal = "TODO-SHOULD-BE-CONFIGURABLE" - const constructorArguments = [nexusAddress, mtaAddress, votiumBribeAddress, votiumBribeProposal] + const constructorArguments = [nexusAddress, mtaAddress, votiumBribeAddress] const votiumBribeForwarder = await deployContract(new VotiumBribeForwarder__factory(signer), "VotiumBribeForwarder", constructorArguments) From bb8b8717c7ba43e631c1107e86eb572b5beaad52 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Mon, 6 Dec 2021 19:27:58 +1100 Subject: [PATCH 6/6] chore: Updated VotiumBribeForwarder Natspec --- contracts/emissions/VotiumBribeForwarder.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/emissions/VotiumBribeForwarder.sol b/contracts/emissions/VotiumBribeForwarder.sol index 5bd76e6b..702ff1ad 100644 --- a/contracts/emissions/VotiumBribeForwarder.sol +++ b/contracts/emissions/VotiumBribeForwarder.sol @@ -8,7 +8,7 @@ import { ImmutableModule } from "../shared/ImmutableModule.sol"; /** * @title VotiumBribeForwarder * @author mStable - * @notice Transfers reward tokens to a list of off-chain calculated recipients and amounts. + * @notice Uses reward tokens to bribe vlCVX holders to vote for a Curve gauge using Votium. * @dev VotiumBribe contract on Mainnet, Polygon, Fantom: 0x19bbc3463dd8d07f55438014b021fb457ebd4595 * @dev VERSION: 1.0 * DATE: 2021-11-03