From cdfa4d4a46377ef79912512d9f5c9b0a21a28c10 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 5 Apr 2023 15:32:36 +0530 Subject: [PATCH 01/12] test: add examples to set emissions per second and distribution end --- ...issionConfigurationTestMATICXPolygon.t.sol | 222 ++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 tests/EmissionConfigurationTestMATICXPolygon.t.sol diff --git a/tests/EmissionConfigurationTestMATICXPolygon.t.sol b/tests/EmissionConfigurationTestMATICXPolygon.t.sol new file mode 100644 index 0000000..f6f516e --- /dev/null +++ b/tests/EmissionConfigurationTestMATICXPolygon.t.sol @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import {IERC20} from 'forge-std/interfaces/IERC20.sol'; +import {AaveV3Polygon, AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol'; +import {IAaveIncentivesController} from '../src/interfaces/IAaveIncentivesController.sol'; +import {IEmissionManager, ITransferStrategyBase, RewardsDataTypes, IEACAggregatorProxy} from '../src/interfaces/IEmissionManager.sol'; +import {BaseTest} from './utils/BaseTest.sol'; + +contract EmissionConfigurationTestMATICXPolygon is BaseTest { + /// @dev Used to simplify the definition of a program of emissions + /// @param asset The asset on which to put reward on, usually Aave aTokens or vTokens (variable debt tokens) + /// @param emission Total emission of a `reward` token during the whole distribution duration defined + /// E.g. With an emission of 10_000 MATICX tokens during 1 month, an emission of 50% for variableDebtPolWMATIC would be + /// 10_000 * 1e18 * 50% / 30 days in seconds = 1_000 * 1e18 / 2_592_000 = ~ 0.0003858 * 1e18 MATICX per second + struct EmissionPerAsset { + address asset; + uint256 emission; + } + + address constant EMISSION_ADMIN = 0x0c54a0BCCF5079478a144dBae1AFcb4FEdf7b263; // Polygon Foundation + address constant REWARD_ASSET = AaveV3PolygonAssets.MaticX_UNDERLYING; + IEACAggregatorProxy constant REWARD_ORACLE = + IEACAggregatorProxy(AaveV3PolygonAssets.MaticX_ORACLE); + + /// @dev already deployed and configured for the both the MATICX asset and the 0x0c54a0BCCF5079478a144dBae1AFcb4FEdf7b263 + /// EMISSION_ADMIN + ITransferStrategyBase constant TRANSFER_STRATEGY = + ITransferStrategyBase(0x53F57eAAD604307889D87b747Fc67ea9DE430B01); + + uint256 constant TOTAL_DISTRIBUTION = 60_000 ether; // 10'000 MATICX/month, 6 months + uint88 constant DURATION_DISTRIBUTION = 180 days; + + uint256 constant NEW_TOTAL_DISTRIBUTION = 30_000 ether; + uint88 constant NEW_DURATION_DISTRIBUTION_END = 15 days; + + address MATICX_WHALE = 0xBA12222222228d8Ba445958a75a0704d566BF2C8; + address vWMATIC_WHALE = 0xe52F5349153b8eb3B89675AF45aC7502C4997E6A; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('polygon'), 39361970); + } + + function test_setEmissionPerSecond() public { + vm.startPrank(EMISSION_ADMIN); + + IERC20(REWARD_ASSET).approve(address(TRANSFER_STRATEGY), TOTAL_DISTRIBUTION); + IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).configureAssets(_getAssetConfigs()); + + vm.stopPrank(); + + vm.startPrank(MATICX_WHALE); + IERC20(REWARD_ASSET).transfer(EMISSION_ADMIN, 50_000 ether); + vm.stopPrank(); + + address[] memory rewards = new address[](1); + rewards[0] = REWARD_ASSET; + + uint88[] memory newEmissionsPerSecond = new uint88[](1); + newEmissionsPerSecond[0] = _toUint88(NEW_TOTAL_DISTRIBUTION / DURATION_DISTRIBUTION); + + // The emission admin can change the emission per second of the reward after the rewards have been configured. + // Here we change the initial emission per second to the new one. + vm.startPrank(EMISSION_ADMIN); + IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).setEmissionPerSecond( + AaveV3PolygonAssets.WMATIC_V_TOKEN, + rewards, + newEmissionsPerSecond + ); + emit log_named_bytes( + 'calldata to execute tx on EMISSION_MANAGER to set the new emission per second from the emissions admin (safe)', + abi.encodeWithSelector( + IEmissionManager.setEmissionPerSecond.selector, + AaveV3PolygonAssets.WMATIC_V_TOKEN, + rewards, + newEmissionsPerSecond + ) + ); + vm.stopPrank(); + + vm.warp(block.timestamp + 30 days); + + address[] memory assets = new address[](1); + assets[0] = AaveV3PolygonAssets.WMATIC_V_TOKEN; + + uint256 balanceBefore = IERC20(REWARD_ASSET).balanceOf(vWMATIC_WHALE); + + vm.startPrank(vWMATIC_WHALE); + + IAaveIncentivesController(AaveV3Polygon.DEFAULT_INCENTIVES_CONTROLLER).claimRewards( + assets, + type(uint256).max, + vWMATIC_WHALE, + REWARD_ASSET + ); + + vm.stopPrank(); + + uint256 balanceAfter = IERC20(REWARD_ASSET).balanceOf(vWMATIC_WHALE); + + // Approx estimated rewards with current emission in 1 month, considering the new emissions per second set. + uint256 deviationAccepted = 650 ether; + assertApproxEqAbs( + balanceBefore, + balanceAfter, + deviationAccepted, + 'Invalid delta on claimed rewards' + ); + } + + function test_setDistributionEnd() public { + vm.startPrank(EMISSION_ADMIN); + + IERC20(REWARD_ASSET).approve(address(TRANSFER_STRATEGY), TOTAL_DISTRIBUTION); + + IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).configureAssets(_getAssetConfigs()); + + vm.stopPrank(); + + vm.startPrank(MATICX_WHALE); + IERC20(REWARD_ASSET).transfer(EMISSION_ADMIN, 50_000 ether); + vm.stopPrank(); + + // The emission admin can change the distribution end of the reward after the rewards have been configured. + // Here we change the distribution end to the new one. + vm.startPrank(EMISSION_ADMIN); + + IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).setDistributionEnd( + AaveV3PolygonAssets.WMATIC_V_TOKEN, + REWARD_ASSET, + _toUint32(block.timestamp + NEW_DURATION_DISTRIBUTION_END) + ); + emit log_named_bytes( + 'calldata to execute tx on EMISSION_MANAGER to set the new distribution end from the emissions admin (safe)', + abi.encodeWithSelector( + IEmissionManager.setDistributionEnd.selector, + AaveV3PolygonAssets.WMATIC_V_TOKEN, + REWARD_ASSET, + block.timestamp + NEW_DURATION_DISTRIBUTION_END + ) + ); + + vm.stopPrank(); + + vm.warp(block.timestamp + 30 days); + + vm.startPrank(vWMATIC_WHALE); + + address[] memory assets = new address[](1); + assets[0] = AaveV3PolygonAssets.WMATIC_V_TOKEN; + + uint256 balanceBefore = IERC20(REWARD_ASSET).balanceOf(vWMATIC_WHALE); + + IAaveIncentivesController(AaveV3Polygon.DEFAULT_INCENTIVES_CONTROLLER).claimRewards( + assets, + type(uint256).max, + vWMATIC_WHALE, + REWARD_ASSET + ); + + uint256 balanceAfter = IERC20(REWARD_ASSET).balanceOf(vWMATIC_WHALE); + + // Approx estimated rewards with current emission in 15 days, as we changed the distribution end. + uint256 deviationAccepted = 650 ether; + assertApproxEqAbs( + balanceBefore, + balanceAfter, + deviationAccepted, + 'Invalid delta on claimed rewards' + ); + + vm.stopPrank(); + } + + function _getAssetConfigs() internal view returns (RewardsDataTypes.RewardsConfigInput[] memory) { + uint32 distributionEnd = uint32(block.timestamp + DURATION_DISTRIBUTION); + + EmissionPerAsset[] memory emissionsPerAsset = _getEmissionsPerAsset(); + + RewardsDataTypes.RewardsConfigInput[] + memory configs = new RewardsDataTypes.RewardsConfigInput[](emissionsPerAsset.length); + for (uint256 i = 0; i < emissionsPerAsset.length; i++) { + configs[i] = RewardsDataTypes.RewardsConfigInput({ + emissionPerSecond: _toUint88(emissionsPerAsset[i].emission / DURATION_DISTRIBUTION), + totalSupply: 0, // IMPORTANT this will not be taken into account by the contracts, so 0 is fine + distributionEnd: distributionEnd, + asset: emissionsPerAsset[i].asset, + reward: REWARD_ASSET, + transferStrategy: TRANSFER_STRATEGY, + rewardOracle: REWARD_ORACLE + }); + } + + return configs; + } + + function _getEmissionsPerAsset() internal pure returns (EmissionPerAsset[] memory) { + EmissionPerAsset[] memory emissionsPerAsset = new EmissionPerAsset[](1); + emissionsPerAsset[0] = EmissionPerAsset({ + asset: AaveV3PolygonAssets.WMATIC_V_TOKEN, + emission: TOTAL_DISTRIBUTION // 100% of the distribution + }); + + uint256 totalDistribution; + for (uint256 i = 0; i < emissionsPerAsset.length; i++) { + totalDistribution += emissionsPerAsset[i].emission; + } + require(totalDistribution == TOTAL_DISTRIBUTION, 'INVALID_SUM_OF_EMISSIONS'); + + return emissionsPerAsset; + } + + function _toUint88(uint256 value) internal pure returns (uint88) { + require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); + return uint88(value); + } + + function _toUint32(uint256 value) internal pure returns (uint32) { + require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); + return uint32(value); + } +} From 54e02f653d947b0eb1b33e0627cc63a360c751a2 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 5 Apr 2023 16:44:00 +0530 Subject: [PATCH 02/12] refactor: some internal function --- ...issionConfigurationTestMATICXPolygon.t.sol | 81 ++++++++++++++----- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/tests/EmissionConfigurationTestMATICXPolygon.t.sol b/tests/EmissionConfigurationTestMATICXPolygon.t.sol index f6f516e..67ce4ea 100644 --- a/tests/EmissionConfigurationTestMATICXPolygon.t.sol +++ b/tests/EmissionConfigurationTestMATICXPolygon.t.sol @@ -18,6 +18,26 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { uint256 emission; } + /// @dev Used to simplify the configuration of new emissions per second after the emissions program has been created + /// @param asset The asset for which new emissions per second needs to be configured + /// @param rewards The rewards for which new emissions per second needs to be configured + /// @param newEmissionsPerSecond The new emissions per second of the `reward` tokens + struct NewEmissionPerAsset { + address asset; + address[] rewards; + uint88[] newEmissionsPerSecond; + } + + /// @dev Used to simplify the configuration of new distribution end after the emissions program has been created + /// @param asset The asset for which new distribution end needs to be configured + /// @param reward The reward for which new distribution end needs to be configured + /// @param newDistributionEnd The new distribution end of the asset and reward + struct NewDistributionEndPerAsset { + address asset; + address reward; + uint32 newDistributionEnd; + } + address constant EMISSION_ADMIN = 0x0c54a0BCCF5079478a144dBae1AFcb4FEdf7b263; // Polygon Foundation address constant REWARD_ASSET = AaveV3PolygonAssets.MaticX_UNDERLYING; IEACAggregatorProxy constant REWARD_ORACLE = @@ -41,7 +61,7 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { vm.createSelectFork(vm.rpcUrl('polygon'), 39361970); } - function test_setEmissionPerSecond() public { + function test_setNewEmissionPerSecond() public { vm.startPrank(EMISSION_ADMIN); IERC20(REWARD_ASSET).approve(address(TRANSFER_STRATEGY), TOTAL_DISTRIBUTION); @@ -53,27 +73,23 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { IERC20(REWARD_ASSET).transfer(EMISSION_ADMIN, 50_000 ether); vm.stopPrank(); - address[] memory rewards = new address[](1); - rewards[0] = REWARD_ASSET; - - uint88[] memory newEmissionsPerSecond = new uint88[](1); - newEmissionsPerSecond[0] = _toUint88(NEW_TOTAL_DISTRIBUTION / DURATION_DISTRIBUTION); + NewEmissionPerAsset memory newEmissionPerAsset = _getNewEmissionPerSecond(); // The emission admin can change the emission per second of the reward after the rewards have been configured. // Here we change the initial emission per second to the new one. vm.startPrank(EMISSION_ADMIN); IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).setEmissionPerSecond( - AaveV3PolygonAssets.WMATIC_V_TOKEN, - rewards, - newEmissionsPerSecond + newEmissionPerAsset.asset, + newEmissionPerAsset.rewards, + newEmissionPerAsset.newEmissionsPerSecond ); emit log_named_bytes( 'calldata to execute tx on EMISSION_MANAGER to set the new emission per second from the emissions admin (safe)', abi.encodeWithSelector( IEmissionManager.setEmissionPerSecond.selector, - AaveV3PolygonAssets.WMATIC_V_TOKEN, - rewards, - newEmissionsPerSecond + newEmissionPerAsset.asset, + newEmissionPerAsset.rewards, + newEmissionPerAsset.newEmissionsPerSecond ) ); vm.stopPrank(); @@ -108,7 +124,7 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { ); } - function test_setDistributionEnd() public { + function test_setNewDistributionEnd() public { vm.startPrank(EMISSION_ADMIN); IERC20(REWARD_ASSET).approve(address(TRANSFER_STRATEGY), TOTAL_DISTRIBUTION); @@ -125,18 +141,20 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { // Here we change the distribution end to the new one. vm.startPrank(EMISSION_ADMIN); + NewDistributionEndPerAsset memory newDistributionEndPerAsset = _getNewDistributionEnd(); + IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).setDistributionEnd( - AaveV3PolygonAssets.WMATIC_V_TOKEN, - REWARD_ASSET, - _toUint32(block.timestamp + NEW_DURATION_DISTRIBUTION_END) + newDistributionEndPerAsset.asset, + newDistributionEndPerAsset.reward, + newDistributionEndPerAsset.newDistributionEnd ); emit log_named_bytes( 'calldata to execute tx on EMISSION_MANAGER to set the new distribution end from the emissions admin (safe)', abi.encodeWithSelector( IEmissionManager.setDistributionEnd.selector, - AaveV3PolygonAssets.WMATIC_V_TOKEN, - REWARD_ASSET, - block.timestamp + NEW_DURATION_DISTRIBUTION_END + newDistributionEndPerAsset.asset, + newDistributionEndPerAsset.reward, + newDistributionEndPerAsset.newDistributionEnd ) ); @@ -210,6 +228,31 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { return emissionsPerAsset; } + function _getNewEmissionPerSecond() internal pure returns (NewEmissionPerAsset memory) { + NewEmissionPerAsset memory newEmissionPerAsset; + + address[] memory rewards = new address[](1); + rewards[0] = REWARD_ASSET; + uint88[] memory newEmissionsPerSecond = new uint88[](1); + newEmissionsPerSecond[0] = _toUint88(NEW_TOTAL_DISTRIBUTION / DURATION_DISTRIBUTION); + + newEmissionPerAsset.asset = AaveV3PolygonAssets.WMATIC_V_TOKEN; + newEmissionPerAsset.rewards = rewards; + newEmissionPerAsset.newEmissionsPerSecond = newEmissionsPerSecond; + + return newEmissionPerAsset; + } + + function _getNewDistributionEnd() internal view returns (NewDistributionEndPerAsset memory) { + NewDistributionEndPerAsset memory newDistributionEndPerAsset; + + newDistributionEndPerAsset.asset = AaveV3PolygonAssets.WMATIC_V_TOKEN; + newDistributionEndPerAsset.reward = REWARD_ASSET; + newDistributionEndPerAsset.newDistributionEnd = _toUint32(block.timestamp + NEW_DURATION_DISTRIBUTION_END); + + return newDistributionEndPerAsset; + } + function _toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); From 466128d7767451d7c84bc569e331e3e627c3cf87 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 5 Apr 2023 16:59:43 +0530 Subject: [PATCH 03/12] docs: update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 167c451..8ea0d17 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ This repository contains: - an [example proposal](./src/contracts/AddEmissionAdminPayload.sol) payload which could be used to setup liquidity mining on a governance controlled aave v3 pool - a [test](./tests/EmissionTestOpOptimism.t.sol) simulating the configuration of certain assets to receive liquidity mining +- a [test](./tests/EmissionConfigurationTestMATICXPolygon.t.sol) simulating the setting up of new configuration of certain assets after the liquidity mining program has been created ## How to modify emissions of the LM program? @@ -12,6 +13,14 @@ The emissions can be modified there, with the only requirement being that `sum(a You can run the test via `forge test -vv` which will emit the selector encoded calldata for `configureAssets` on the emission admin which you can use to execute the configuration changes e.g. via Safe. +## How to configure emissions after the LM program has been created? + +After the LM program has been created, the emissions per second and the distribution end could be changed later on by the emissions admin to reduce the LM rewards or change the end date for the distribution. This can be done by calling `setEmissionPerSecond()` and `setDistributionEnd()` on the Emission Manager contract. The test examples on [EmissionConfigurationTestMATICXPolygon.t.sol](./tests/EmissionConfigurationTestMATICXPolygon.t.sol) shows how to do so. + +The function `_getNewEmissionPerSecond()` and `_getNewDistributionEnd()` defines the new emissions per second and new distribution end for the particular case, which could be modified there to change to modified emissions per second and distribution end. + +Similarly you can also run the test via `forge test -vv` which will emit the selector encoded calldata for `setEmissionPerSecond` and `setDistributionEnd` which can be used to make the configuration changes. + ### Setup ```sh From aff7b731b79080afa385ce5f2585ae369494c2dc Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 5 Apr 2023 19:22:54 +0530 Subject: [PATCH 04/12] fix: fork block --- ...issionConfigurationTestMATICXPolygon.t.sol | 108 +++--------------- 1 file changed, 15 insertions(+), 93 deletions(-) diff --git a/tests/EmissionConfigurationTestMATICXPolygon.t.sol b/tests/EmissionConfigurationTestMATICXPolygon.t.sol index 67ce4ea..c9ca45b 100644 --- a/tests/EmissionConfigurationTestMATICXPolygon.t.sol +++ b/tests/EmissionConfigurationTestMATICXPolygon.t.sol @@ -4,20 +4,10 @@ pragma solidity ^0.8.17; import {IERC20} from 'forge-std/interfaces/IERC20.sol'; import {AaveV3Polygon, AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol'; import {IAaveIncentivesController} from '../src/interfaces/IAaveIncentivesController.sol'; -import {IEmissionManager, ITransferStrategyBase, RewardsDataTypes, IEACAggregatorProxy} from '../src/interfaces/IEmissionManager.sol'; +import {IEmissionManager} from '../src/interfaces/IEmissionManager.sol'; import {BaseTest} from './utils/BaseTest.sol'; contract EmissionConfigurationTestMATICXPolygon is BaseTest { - /// @dev Used to simplify the definition of a program of emissions - /// @param asset The asset on which to put reward on, usually Aave aTokens or vTokens (variable debt tokens) - /// @param emission Total emission of a `reward` token during the whole distribution duration defined - /// E.g. With an emission of 10_000 MATICX tokens during 1 month, an emission of 50% for variableDebtPolWMATIC would be - /// 10_000 * 1e18 * 50% / 30 days in seconds = 1_000 * 1e18 / 2_592_000 = ~ 0.0003858 * 1e18 MATICX per second - struct EmissionPerAsset { - address asset; - uint256 emission; - } - /// @dev Used to simplify the configuration of new emissions per second after the emissions program has been created /// @param asset The asset for which new emissions per second needs to be configured /// @param rewards The rewards for which new emissions per second needs to be configured @@ -40,44 +30,25 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { address constant EMISSION_ADMIN = 0x0c54a0BCCF5079478a144dBae1AFcb4FEdf7b263; // Polygon Foundation address constant REWARD_ASSET = AaveV3PolygonAssets.MaticX_UNDERLYING; - IEACAggregatorProxy constant REWARD_ORACLE = - IEACAggregatorProxy(AaveV3PolygonAssets.MaticX_ORACLE); - - /// @dev already deployed and configured for the both the MATICX asset and the 0x0c54a0BCCF5079478a144dBae1AFcb4FEdf7b263 - /// EMISSION_ADMIN - ITransferStrategyBase constant TRANSFER_STRATEGY = - ITransferStrategyBase(0x53F57eAAD604307889D87b747Fc67ea9DE430B01); - - uint256 constant TOTAL_DISTRIBUTION = 60_000 ether; // 10'000 MATICX/month, 6 months - uint88 constant DURATION_DISTRIBUTION = 180 days; uint256 constant NEW_TOTAL_DISTRIBUTION = 30_000 ether; uint88 constant NEW_DURATION_DISTRIBUTION_END = 15 days; + uint88 constant DURATION_DISTRIBUTION = 180 days; - address MATICX_WHALE = 0xBA12222222228d8Ba445958a75a0704d566BF2C8; address vWMATIC_WHALE = 0xe52F5349153b8eb3B89675AF45aC7502C4997E6A; function setUp() public { - vm.createSelectFork(vm.rpcUrl('polygon'), 39361970); + // For this block LM for MATICX has already been initialized + vm.createSelectFork(vm.rpcUrl('polygon'), 41047588); } function test_setNewEmissionPerSecond() public { - vm.startPrank(EMISSION_ADMIN); - - IERC20(REWARD_ASSET).approve(address(TRANSFER_STRATEGY), TOTAL_DISTRIBUTION); - IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).configureAssets(_getAssetConfigs()); - - vm.stopPrank(); - - vm.startPrank(MATICX_WHALE); - IERC20(REWARD_ASSET).transfer(EMISSION_ADMIN, 50_000 ether); - vm.stopPrank(); - NewEmissionPerAsset memory newEmissionPerAsset = _getNewEmissionPerSecond(); + vm.startPrank(EMISSION_ADMIN); + // The emission admin can change the emission per second of the reward after the rewards have been configured. // Here we change the initial emission per second to the new one. - vm.startPrank(EMISSION_ADMIN); IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).setEmissionPerSecond( newEmissionPerAsset.asset, newEmissionPerAsset.rewards, @@ -92,6 +63,7 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { newEmissionPerAsset.newEmissionsPerSecond ) ); + vm.stopPrank(); vm.warp(block.timestamp + 30 days); @@ -125,24 +97,10 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { } function test_setNewDistributionEnd() public { - vm.startPrank(EMISSION_ADMIN); - - IERC20(REWARD_ASSET).approve(address(TRANSFER_STRATEGY), TOTAL_DISTRIBUTION); - - IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).configureAssets(_getAssetConfigs()); - - vm.stopPrank(); - - vm.startPrank(MATICX_WHALE); - IERC20(REWARD_ASSET).transfer(EMISSION_ADMIN, 50_000 ether); - vm.stopPrank(); + NewDistributionEndPerAsset memory newDistributionEndPerAsset = _getNewDistributionEnd(); - // The emission admin can change the distribution end of the reward after the rewards have been configured. - // Here we change the distribution end to the new one. vm.startPrank(EMISSION_ADMIN); - NewDistributionEndPerAsset memory newDistributionEndPerAsset = _getNewDistributionEnd(); - IEmissionManager(AaveV3Polygon.EMISSION_MANAGER).setDistributionEnd( newDistributionEndPerAsset.asset, newDistributionEndPerAsset.reward, @@ -162,13 +120,13 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { vm.warp(block.timestamp + 30 days); - vm.startPrank(vWMATIC_WHALE); - address[] memory assets = new address[](1); assets[0] = AaveV3PolygonAssets.WMATIC_V_TOKEN; uint256 balanceBefore = IERC20(REWARD_ASSET).balanceOf(vWMATIC_WHALE); + vm.startPrank(vWMATIC_WHALE); + IAaveIncentivesController(AaveV3Polygon.DEFAULT_INCENTIVES_CONTROLLER).claimRewards( assets, type(uint256).max, @@ -176,6 +134,8 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { REWARD_ASSET ); + vm.stopPrank(); + uint256 balanceAfter = IERC20(REWARD_ASSET).balanceOf(vWMATIC_WHALE); // Approx estimated rewards with current emission in 15 days, as we changed the distribution end. @@ -186,46 +146,6 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { deviationAccepted, 'Invalid delta on claimed rewards' ); - - vm.stopPrank(); - } - - function _getAssetConfigs() internal view returns (RewardsDataTypes.RewardsConfigInput[] memory) { - uint32 distributionEnd = uint32(block.timestamp + DURATION_DISTRIBUTION); - - EmissionPerAsset[] memory emissionsPerAsset = _getEmissionsPerAsset(); - - RewardsDataTypes.RewardsConfigInput[] - memory configs = new RewardsDataTypes.RewardsConfigInput[](emissionsPerAsset.length); - for (uint256 i = 0; i < emissionsPerAsset.length; i++) { - configs[i] = RewardsDataTypes.RewardsConfigInput({ - emissionPerSecond: _toUint88(emissionsPerAsset[i].emission / DURATION_DISTRIBUTION), - totalSupply: 0, // IMPORTANT this will not be taken into account by the contracts, so 0 is fine - distributionEnd: distributionEnd, - asset: emissionsPerAsset[i].asset, - reward: REWARD_ASSET, - transferStrategy: TRANSFER_STRATEGY, - rewardOracle: REWARD_ORACLE - }); - } - - return configs; - } - - function _getEmissionsPerAsset() internal pure returns (EmissionPerAsset[] memory) { - EmissionPerAsset[] memory emissionsPerAsset = new EmissionPerAsset[](1); - emissionsPerAsset[0] = EmissionPerAsset({ - asset: AaveV3PolygonAssets.WMATIC_V_TOKEN, - emission: TOTAL_DISTRIBUTION // 100% of the distribution - }); - - uint256 totalDistribution; - for (uint256 i = 0; i < emissionsPerAsset.length; i++) { - totalDistribution += emissionsPerAsset[i].emission; - } - require(totalDistribution == TOTAL_DISTRIBUTION, 'INVALID_SUM_OF_EMISSIONS'); - - return emissionsPerAsset; } function _getNewEmissionPerSecond() internal pure returns (NewEmissionPerAsset memory) { @@ -248,7 +168,9 @@ contract EmissionConfigurationTestMATICXPolygon is BaseTest { newDistributionEndPerAsset.asset = AaveV3PolygonAssets.WMATIC_V_TOKEN; newDistributionEndPerAsset.reward = REWARD_ASSET; - newDistributionEndPerAsset.newDistributionEnd = _toUint32(block.timestamp + NEW_DURATION_DISTRIBUTION_END); + newDistributionEndPerAsset.newDistributionEnd = _toUint32( + block.timestamp + NEW_DURATION_DISTRIBUTION_END + ); return newDistributionEndPerAsset; } From 77b4da27b79ebfa725f9ec7f57e0b8b54c204e2d Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Thu, 6 Apr 2023 13:03:18 +0530 Subject: [PATCH 05/12] docs: update README.me with some more info --- README.md | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/README.md b/README.md index 8ea0d17..9afd7a3 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,82 @@ This repository contains: - a [test](./tests/EmissionTestOpOptimism.t.sol) simulating the configuration of certain assets to receive liquidity mining - a [test](./tests/EmissionConfigurationTestMATICXPolygon.t.sol) simulating the setting up of new configuration of certain assets after the liquidity mining program has been created +## Instructions to activate Liquidity Mining on Aave V3: + +Screenshot 2023-04-06 at 12 47 24 PM + +1. Make sure the rewards funds that are needed to be distributed for Liquidity Mining are present in the Emission Admin address. + + _Note: The Emission Admin is an address which has access to manange and configure the reward emissions by calling the Emission Manager contract._ + +2. Do an ERC-20 approve of the total rewards to be distributed to the Transfer Strategy contract, this is contract by Aave which helps to pull the Liquidity Mining rewards from the Emission Admin address to distribute to the user. To know more about how Transfer Strategy contract works you can check [here](https://github.com/aave/aave-v3-periphery/blob/master/docs/rewards/rewards-transfer-strategies.md). + + _Note: The general type of Transfer Strategy contract used for Liquidity Mining is of type PullRewardsStrategy._ + +3. Finally we need to configure the Liquidity Mining emissions on the Emission Manager contract by calling the `configureAssets()` function which will take the array of the following struct to configure liquidity mining for mulitple assets for the same reward or multiple assets for mutiple rewards. + + ``` + EMISSION_MANAGER.configureAssets([{ + + emissionPerSecond: The emission per second following rewards unit decimals. + + totalSupply: The total supply of the asset to incentivize. This should be kept as 0 as the Emissions Manager will fill this up. + + distributionEnd: The end of the distribution of rewards (in seconds). + + asset: The asset for which rewards should be given. Should be the address of the aave aToken (for deposit) or debtToken (for borrow). + In case where the asset for reward is for debt token please put the address of stable debt token for rewards in stable borrow mode + and address of variable debt token for rewards in variable borrow mode. + + reward: The reward token address to be used for Liquidity Mining for the asset. + + transferStrategy: The address of transfer strategy contract. + + rewardOracle: The Chainlink Aggregator compatible Price Oracle of the reward. + + }]) + ``` + +Below is an example with the pseudo code to activate Liquidity Mining for the variable borrow of `wMatic` with `MaticX` as the reward token for the total amount of `60,000` `MaticX` for the total duration of `6 months`. For a more detailed explanation checkout this [test](./tests/EmissionTestMATICXPolygon.t.sol). + +1. Make sure EMISSION_ADMIN has sufficient balance of the MaticX token. + + ``` + IERC20(MATIC_X_ADDRESS).balanceOf(EMISSION_ADMIN) > 60000 *1e18 + ``` + +2. Do an ERC-20 approve from the MaticX token to the transfer strategy contract for the total amount. + + ``` + IERC20(MATIC_X_ADDRESS).approve(TRANSFER_STRATEGY_ADDRESS, 60000 *1e18); + ``` + +3. Configure the Liquidity Mining emissions on the Emission Manager contract. + + ``` + EMISSION_MANAGER.configureAssets([{ + + emissionPerSecond: 60000 * 1e18 / (180 days in seconds) + + totalSupply: 0 + + distributionEnd: current timestamp + (180 days in seconds) + + asset: Aave Variable Debt Token of wMatic // 0x4a1c3aD6Ed28a636ee1751C69071f6be75DEb8B8 + + reward: MaticX Token address // 0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6 + + transferStrategy: ITransferStrategyBase(STRATEGY_ADDRESS) // 0x53F57eAAD604307889D87b747Fc67ea9DE430B01 + + rewardOracle: IEACAggregatorProxy(MaticX_ORACLE_ADDRESS) // 0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403 + + }]) + ``` + +Awesome! so liquidity mining has been succefully configured now. + +After the Liquidity Mining has been set, we can also configure later on to increase or decrease the rewards (emissions per second) and to change the end date for liquidity mining. More info on this below. + ## How to modify emissions of the LM program? The function `_getEmissionsPerAsset()` on [EmissionTestOpOptimism.t.sol](./tests/EmissionTestOpOptimism.t.sol) defines the exact emissions for the particular case of $OP as reward token and a total distribution of 5'000'000 $OP during exactly 90 days. @@ -21,6 +97,29 @@ The function `_getNewEmissionPerSecond()` and `_getNewDistributionEnd()` defines Similarly you can also run the test via `forge test -vv` which will emit the selector encoded calldata for `setEmissionPerSecond` and `setDistributionEnd` which can be used to make the configuration changes. +## FAQ's: + +- Do we need to have and approve the whole liquidity mining reward initially? + + It is generally advisable to have and approve funds for the duration of the next 3 months of the Liquidity Mining Program. However it is the choice of the Emission Admin to do it progressively as well, as the users accrue rewards over time. + +- Can we configure mutiple rewards for the same asset? + + Yes, Liquidity Mining could be configured for multiple rewards for the same asset. + +- Why do we need to approve funds to the Aave Transfer Strategy contract? + + This is needed so the Transfer Strategy contract can pull the rewards from the Emission Admin to distribute it to the user when the user claims them. + +- Can we stop the liquidity mining program at any time? + + Yes, the liquidity mining program could be stopped at any moment by the Emission Admin. + The duration of the Liquidity Mining program could be increased as well, totally the choice of Emission Admin. + +- Can we change the amount of liquidty mining rewards? + + Yes, the liquidity mining rewards could be increased or decreased by the Emission Admin. + ### Setup ```sh From 633002d18a37de1330beba3a614963dd8242aafb Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 10 Apr 2023 12:38:38 +0530 Subject: [PATCH 06/12] docs: update README.md --- README.md | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9afd7a3..8ca376a 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,15 @@ This repository contains: ## Instructions to activate Liquidity Mining on Aave V3: -Screenshot 2023-04-06 at 12 47 24 PM +Screenshot 2023-04-10 at 11 27 10 AM -1. Make sure the rewards funds that are needed to be distributed for Liquidity Mining are present in the Emission Admin address. +1. Make sure the rewards funds that are needed to be distributed for Liquidity Mining are present in the Rewards Vault. - _Note: The Emission Admin is an address which has access to manange and configure the reward emissions by calling the Emission Manager contract._ +2. Do an ERC-20 approve of the total rewards to be distributed to the Transfer Strategy contract, this is contract by Aave which helps to pull the Liquidity Mining rewards from the Rewards Vault address to distribute to the user. To know more about how Transfer Strategy contract works you can check [here](https://github.com/aave/aave-v3-periphery/blob/master/docs/rewards/rewards-transfer-strategies.md). -2. Do an ERC-20 approve of the total rewards to be distributed to the Transfer Strategy contract, this is contract by Aave which helps to pull the Liquidity Mining rewards from the Emission Admin address to distribute to the user. To know more about how Transfer Strategy contract works you can check [here](https://github.com/aave/aave-v3-periphery/blob/master/docs/rewards/rewards-transfer-strategies.md). + _Note: The Emission Admin is an address which has access to manange and configure the reward emissions by calling the Emission Manager contract and the general type of Transfer Strategy contract used for Liquidity Mining is of type PullRewardsStrategy._ - _Note: The general type of Transfer Strategy contract used for Liquidity Mining is of type PullRewardsStrategy._ - -3. Finally we need to configure the Liquidity Mining emissions on the Emission Manager contract by calling the `configureAssets()` function which will take the array of the following struct to configure liquidity mining for mulitple assets for the same reward or multiple assets for mutiple rewards. +3. Finally we need to configure the Liquidity Mining emissions on the Emission Manager contract from the Emission Admin by calling the `configureAssets()` function which will take the array of the following struct to configure liquidity mining for mulitple assets for the same reward or multiple assets for mutiple rewards. ``` EMISSION_MANAGER.configureAssets([{ @@ -44,13 +42,13 @@ This repository contains: Below is an example with the pseudo code to activate Liquidity Mining for the variable borrow of `wMatic` with `MaticX` as the reward token for the total amount of `60,000` `MaticX` for the total duration of `6 months`. For a more detailed explanation checkout this [test](./tests/EmissionTestMATICXPolygon.t.sol). -1. Make sure EMISSION_ADMIN has sufficient balance of the MaticX token. +1. Make sure the Rewards Vault has sufficient balance of the MaticX token. ``` - IERC20(MATIC_X_ADDRESS).balanceOf(EMISSION_ADMIN) > 60000 *1e18 + IERC20(MATIC_X_ADDRESS).balanceOf(REWARDS_VAULT) > 60000 *1e18 ``` -2. Do an ERC-20 approve from the MaticX token to the transfer strategy contract for the total amount. +2. Do an ERC-20 approve from the MaticX token from the Rewards Vault to the transfer strategy contract for the total amount. ``` IERC20(MATIC_X_ADDRESS).approve(TRANSFER_STRATEGY_ADDRESS, 60000 *1e18); @@ -89,6 +87,8 @@ The emissions can be modified there, with the only requirement being that `sum(a You can run the test via `forge test -vv` which will emit the selector encoded calldata for `configureAssets` on the emission admin which you can use to execute the configuration changes e.g. via Safe. +_Note: The test example above uses total distribution and duration distribution just for convenience to define emissions per second, in reality as we only pass emissions per second to `configureAssets()` we could define it in any way we wish._ + ## How to configure emissions after the LM program has been created? After the LM program has been created, the emissions per second and the distribution end could be changed later on by the emissions admin to reduce the LM rewards or change the end date for the distribution. This can be done by calling `setEmissionPerSecond()` and `setDistributionEnd()` on the Emission Manager contract. The test examples on [EmissionConfigurationTestMATICXPolygon.t.sol](./tests/EmissionConfigurationTestMATICXPolygon.t.sol) shows how to do so. @@ -107,9 +107,26 @@ Similarly you can also run the test via `forge test -vv` which will emit the sel Yes, Liquidity Mining could be configured for multiple rewards for the same asset. -- Why do we need to approve funds to the Aave Transfer Strategy contract? +- Why do we need to approve funds from the Rewards Vault to the Aave Transfer Strategy contract? + + This is needed so the Transfer Strategy contract can pull the rewards from the Rewards Vault to distribute it to the user when the user claims them. + +- Can I reuse an already deployed transfer strategy? + + Yes, a transfer strategy could be reused if it has already been deployed for the given network (given that you want the rewards vault, rewards admin and the incentives controller to be the same). + +- If a transfer strategy does not exist, how do I create one? + + The transfer strategy is an immutable contract which determines the logic of the rewards transfer. To create a new pull reward transfer strategy (most common transfer strategy for liquidity mining) you could use the +[PullRewardsTransferStrategy.sol](https://github.com/aave/aave-v3-periphery/blob/master/contracts/rewards/transfer-strategies/PullRewardsTransferStrategy.sol) contract with the following constructor params: + + - `incentivesController`: address of the incentives controller + - `rewardsAdmin`: address of the incentives controller for access control + - `rewardsVault`: address of the rewards vault containing the funds for the Liquidity Mining program. - This is needed so the Transfer Strategy contract can pull the rewards from the Emission Admin to distribute it to the user when the user claims them. + Example to deploy a transfer strategy can be found [here](./scripts/RewardsConfigHelpers.s.sol). + + _Note: All transfer strategy should inherit from the base contract [TransferStrategyBase.sol](https://github.com/aave/aave-v3-periphery/blob/master/contracts/rewards/transfer-strategies/TransferStrategyBase.sol) and you could also define your own custom transfer strategy even with NFT’s as rewards, given that you inherit from the base contract._ - Can we stop the liquidity mining program at any time? From 45e7403d06a63aa23446001e755f313ccc3ae990 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 23 May 2023 18:42:48 +0530 Subject: [PATCH 07/12] docs: fix README Co-authored-by: Ernesto Boado --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ca376a..8192af8 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This repository contains: 2. Do an ERC-20 approve of the total rewards to be distributed to the Transfer Strategy contract, this is contract by Aave which helps to pull the Liquidity Mining rewards from the Rewards Vault address to distribute to the user. To know more about how Transfer Strategy contract works you can check [here](https://github.com/aave/aave-v3-periphery/blob/master/docs/rewards/rewards-transfer-strategies.md). - _Note: The Emission Admin is an address which has access to manange and configure the reward emissions by calling the Emission Manager contract and the general type of Transfer Strategy contract used for Liquidity Mining is of type PullRewardsStrategy._ + _Note: The Emission Admin is an address which has access to manage and configure the reward emissions by calling the Emission Manager contract and the general type of Transfer Strategy contract used for Liquidity Mining is of type PullRewardsStrategy._ 3. Finally we need to configure the Liquidity Mining emissions on the Emission Manager contract from the Emission Admin by calling the `configureAssets()` function which will take the array of the following struct to configure liquidity mining for mulitple assets for the same reward or multiple assets for mutiple rewards. From c3f061a0ba63573bcfca2ddf24f206461b84a9be Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 26 Jun 2023 16:42:23 +0530 Subject: [PATCH 08/12] docs: fix README --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8192af8..ca8e616 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ This repository contains: 1. Make sure the rewards funds that are needed to be distributed for Liquidity Mining are present in the Rewards Vault. + _Note: The Rewards Vault is your address which contains the reward asset._ + 2. Do an ERC-20 approve of the total rewards to be distributed to the Transfer Strategy contract, this is contract by Aave which helps to pull the Liquidity Mining rewards from the Rewards Vault address to distribute to the user. To know more about how Transfer Strategy contract works you can check [here](https://github.com/aave/aave-v3-periphery/blob/master/docs/rewards/rewards-transfer-strategies.md). _Note: The Emission Admin is an address which has access to manage and configure the reward emissions by calling the Emission Manager contract and the general type of Transfer Strategy contract used for Liquidity Mining is of type PullRewardsStrategy._ @@ -35,7 +37,7 @@ This repository contains: transferStrategy: The address of transfer strategy contract. - rewardOracle: The Chainlink Aggregator compatible Price Oracle of the reward. + rewardOracle: The Chainlink Aggregator compatible Price Oracle of the reward (used on off-chain infra like UI for price conversion). }]) ``` @@ -76,10 +78,6 @@ Below is an example with the pseudo code to activate Liquidity Mining for the va }]) ``` -Awesome! so liquidity mining has been succefully configured now. - -After the Liquidity Mining has been set, we can also configure later on to increase or decrease the rewards (emissions per second) and to change the end date for liquidity mining. More info on this below. - ## How to modify emissions of the LM program? The function `_getEmissionsPerAsset()` on [EmissionTestOpOptimism.t.sol](./tests/EmissionTestOpOptimism.t.sol) defines the exact emissions for the particular case of $OP as reward token and a total distribution of 5'000'000 $OP during exactly 90 days. @@ -135,7 +133,8 @@ Similarly you can also run the test via `forge test -vv` which will emit the sel - Can we change the amount of liquidty mining rewards? - Yes, the liquidity mining rewards could be increased or decreased by the Emission Admin. + Yes, the liquidity mining rewards could be increased or decreased by the Emission Admin. To do so, please refer +[here](https://github.com/bgd-labs/example-liquidity-mining-aave-v3/tree/feat/configure-emissions#how-to-configure-emissions-after-the-lm-program-has-been-created) ### Setup From 67bd1a147d9748c9e4c84493cef6bceb44c84ccc Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 26 Jun 2023 17:36:06 +0530 Subject: [PATCH 09/12] docs: fix stop LM README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ca8e616..a4f908f 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ Similarly you can also run the test via `forge test -vv` which will emit the sel Yes, the liquidity mining program could be stopped at any moment by the Emission Admin. The duration of the Liquidity Mining program could be increased as well, totally the choice of Emission Admin. + To stop the liquidity mining, we can either set the emissions per second to 0 or set the distribution end to the block we wish to stop liquiditiy mining at. - Can we change the amount of liquidty mining rewards? From a2bb5f42cca6cc0f4aca7a28743687d892e7c98c Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 26 Jun 2023 17:39:26 +0530 Subject: [PATCH 10/12] fix: add lockfile --- yarn.lock | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..16abce7 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,53 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@solidity-parser/parser@^0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.0.tgz#1fb418c816ca1fc3a1e94b08bcfe623ec4e1add4" + integrity sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +antlr4ts@^0.5.0-alpha.4: + version "0.5.0-alpha.4" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +prettier-plugin-solidity@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" + integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== + dependencies: + "@solidity-parser/parser" "^0.16.0" + semver "^7.3.8" + solidity-comments-extractor "^0.0.7" + +prettier@^2.8.3: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +semver@^7.3.8: + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== + dependencies: + lru-cache "^6.0.0" + +solidity-comments-extractor@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" + integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== From dbee5c471183b3afeb90ff4ffea593393cc96436 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 26 Jun 2023 17:47:07 +0530 Subject: [PATCH 11/12] fix: lockfile --- .gitignore | 2 - package-lock.json | 167 ++++++++++++++++++++++++++++++++++++++++++++++ yarn.lock | 53 --------------- 3 files changed, 167 insertions(+), 55 deletions(-) create mode 100644 package-lock.json delete mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index d95519b..d16445d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,6 @@ out/ .idea .vscode -# well, looks strange to ignore package-lock, but we have only pretter and it's temproray -package-lock.json node_modules # ignore foundry deploy artifacts diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8418297 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,167 @@ +{ + "name": "example-liquidity-mining-aave-v3", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "example-liquidity-mining-aave-v3", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "prettier": "^2.8.3", + "prettier-plugin-solidity": "^1.1.1" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.0.tgz", + "integrity": "sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==", + "dev": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prettier": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-solidity": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz", + "integrity": "sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==", + "dev": true, + "dependencies": { + "@solidity-parser/parser": "^0.16.0", + "semver": "^7.3.8", + "solidity-comments-extractor": "^0.0.7" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "prettier": ">=2.3.0 || >=3.0.0-alpha.0" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/solidity-comments-extractor": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", + "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + }, + "dependencies": { + "@solidity-parser/parser": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.0.tgz", + "integrity": "sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==", + "dev": true, + "requires": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "prettier": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "dev": true + }, + "prettier-plugin-solidity": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz", + "integrity": "sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==", + "dev": true, + "requires": { + "@solidity-parser/parser": "^0.16.0", + "semver": "^7.3.8", + "solidity-comments-extractor": "^0.0.7" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "solidity-comments-extractor": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", + "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 16abce7..0000000 --- a/yarn.lock +++ /dev/null @@ -1,53 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@solidity-parser/parser@^0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.0.tgz#1fb418c816ca1fc3a1e94b08bcfe623ec4e1add4" - integrity sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -antlr4ts@^0.5.0-alpha.4: - version "0.5.0-alpha.4" - resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" - integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -prettier-plugin-solidity@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" - integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== - dependencies: - "@solidity-parser/parser" "^0.16.0" - semver "^7.3.8" - solidity-comments-extractor "^0.0.7" - -prettier@^2.8.3: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -semver@^7.3.8: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== - dependencies: - lru-cache "^6.0.0" - -solidity-comments-extractor@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" - integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== From 0603c0c3c248de755728275d9fb7c8e89b88d7da Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Mon, 26 Jun 2023 17:50:20 +0530 Subject: [PATCH 12/12] fix: add yarn.lock --- yarn.lock | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..16abce7 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,53 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@solidity-parser/parser@^0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.0.tgz#1fb418c816ca1fc3a1e94b08bcfe623ec4e1add4" + integrity sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +antlr4ts@^0.5.0-alpha.4: + version "0.5.0-alpha.4" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +prettier-plugin-solidity@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" + integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== + dependencies: + "@solidity-parser/parser" "^0.16.0" + semver "^7.3.8" + solidity-comments-extractor "^0.0.7" + +prettier@^2.8.3: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +semver@^7.3.8: + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== + dependencies: + lru-cache "^6.0.0" + +solidity-comments-extractor@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" + integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==