Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Generator update permissioned payloads controller #36

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ee562f2
add: temp data
Nov 14, 2024
357af01
add: update support
Nov 15, 2024
ed3d54b
temp files
Nov 15, 2024
9a3bc88
remove: temp files
Nov 15, 2024
da6b470
add: emission admin fixes to satisfy new structure
Nov 16, 2024
679d27d
add: temp files
Nov 16, 2024
741464a
add: new version of setup liquidity mining test
Nov 18, 2024
0c57657
remove: temp files
Nov 18, 2024
78a23dc
fix: generator bug
Nov 18, 2024
f35d8ec
add: temp scripts
Nov 19, 2024
70c76d4
fix: aave-v3-governance update
Nov 19, 2024
bb70677
temp: foundry passing versions
Nov 19, 2024
884c2bb
remove: temp file, extra data from deploy script
Nov 19, 2024
f888823
temp: finalized deploy scripts prototypes
Nov 19, 2024
a575bc7
add: deploy payload generation
Nov 20, 2024
ef2d4b4
fix: test example
Nov 20, 2024
eaf716c
fix: missing file
Nov 21, 2024
8540dc8
fix: tiny review fix
Nov 22, 2024
858445b
refactor: better comment
Nov 22, 2024
913977a
revert: revert bad fix
Nov 22, 2024
c368ddf
fix: test contract generation reward asset name, deploy PermissionedP…
Nov 22, 2024
f35287d
refactor: doc
Nov 22, 2024
355a406
Update generator/templates/liquiditymining.payloaddeployment.template.ts
Cycxyz Dec 3, 2024
31a9861
fix: aave-address-book with new interfaces
Dec 3, 2024
10c0e15
fix: better test examples
Dec 3, 2024
4d1952b
fix: better test generation
Dec 3, 2024
62b946f
fix: revert useless changes
Dec 3, 2024
fe754ad
add: deploy script for private key
Dec 4, 2024
403d6af
fix: test fix
Dec 4, 2024
9823ed3
add: better readme
Dec 4, 2024
7910097
fix: ignore tests in script files
Dec 4, 2024
fe75753
chore: fix remappings (#45)
brotherlymite Dec 5, 2024
d396ca7
fix: review fixes
Dec 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "lib/aave-address-book"]
path = lib/aave-address-book
url = https://github.com/bgd-labs/aave-address-book
[submodule "lib/aave-governance-v3"]
path = lib/aave-governance-v3
url = https://github.com/bgd-labs/aave-governance-v3
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ test :; forge test -vvv
test-sd-rewards :; forge test -vvv --match-contract EmissionTestSDPolygon
test-stmatic-rewards :; forge test -vvv --match-contract EmissionTestSTMATICPolygon
test-maticx-rewards :; forge test -vvv --match-contract EmissionTestMATICXPolygon
deploy-ledger :; forge script ${contract} --rpc-url ${chain} --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} -vvvv --slow --broadcast
deploy-private-key :; forge script ${contract} --rpc-url ${chain} --private-key ${private_key} -vvvv --slow --broadcast

Cycxyz marked this conversation as resolved.
Show resolved Hide resolved
# scripts
deploy-sd-transfer-strategy :; forge script scripts/RewardsConfigHelpers.s.sol:SDDeployTransferStrategy --rpc-url polygon --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
Expand Down
151 changes: 95 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,104 +2,143 @@

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
- an [example proposal](./src/contracts/AddEmissionAdminPayload.sol) payload which could be used to set up 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
- a [test](./tests/EmissionConfigurationTestMATICXPolygon.t.sol) simulating the setting up of a new configuration of certain assets after the liquidity mining program has been created

## Instructions to activate Liquidity Mining on Aave V3:
## Instructions to set up new LM program on Aave V3:

<img width="924" alt="Screenshot 2023-04-10 at 11 27 10 AM" src="https://user-images.githubusercontent.com/22850280/230836420-7b5c4bba-d851-4258-90c6-602d33eaf845.png">
<img src="./proposal_process.png">

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._
_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).
2. Do an ERC-20 approve of the total rewards to be distributed to the Transfer Strategy contract, this is a contract by Aave that helps to pull the Liquidity Mining rewards from the Rewards Vault address to distribute to the user. To know more about how a 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._
_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 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.
3. Encode Emission's Manager `configureAssets()` function call. It takes the array of the following struct to configure liquidity mining for multiple assets for the same reward or multiple assets for multiple rewards.

```
EMISSION_MANAGER.configureAssets([{
_Note: Emission Manager is responsible for configuring emissions of Aave V3. You can interact with it only via the Permissioned Payloads Controller. Permissioned Payloads controller is responsible for storing and executing payloads. It is needed to have a delay between proposal creation and application_

emissionPerSecond: The emission per second following rewards unit decimals.
```
abi.encodeWithSelector(EMISSION_MANAGER.configureAssets.selector, [{

totalSupply: The total supply of the asset to incentivize. This should be kept as 0 as the Emissions Manager will fill this up.
emissionPerSecond: The emission per second following rewards unit decimals.

distributionEnd: The end of the distribution of rewards (in seconds).
totalSupply: The total supply of the asset to incentivize. This should be kept as 0 as the Emissions Manager will fill this up.

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.
distributionEnd: The end of the distribution of rewards (in seconds).

reward: The reward token address to be used for Liquidity Mining for the asset.
asset: The asset for which rewards should be given. Should be the address of the aave aToken (for deposit) or debtToken (for borrow).
In the 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.

transferStrategy: The address of transfer strategy contract.
reward: The reward token address to be used for Liquidity Mining for the asset.

rewardOracle: The Chainlink Aggregator compatible Price Oracle of the reward (used on off-chain infra like UI for price conversion).
transferStrategy: The address of the transfer strategy contract.

}])
```
rewardOracle: The Chainlink Aggregator compatible Price Oracle of the reward (used on off-chain infra like UI for price conversion).

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 the Rewards Vault has sufficient balance of the MaticX token.
4. Finally, to create a proposal on the Permissioned Payloads Controller from the Payloads Manager you need to call the `createPayload()` function which will take the payload received in step 3. Before calling `createPayload()` you'll also need to wrap your payload in the following structure. Each field of the structure shouldn't differ from one proposal to another, except the `calldata` field. To know more about how Permissioned payloads controller works you can check [here](https://github.com/bgd-labs/aave-governance-v3/blob/main/docs/permissioned-payloads-controller-overview.md).

```
IERC20(MATIC_X_ADDRESS).balanceOf(REWARDS_VAULT) > 60000 *1e18
```
_Note: only a user with the Payloads Manager role can create LM configuration proposals. It's needed to interact with the Permissioned Payloads Controller._

2. Do an ERC-20 approve from the MaticX token from the Rewards Vault to the transfer strategy contract for the total amount.
```
PERMISSIONED_PAYLOADS_CONTROLLER.createPayload({

```
IERC20(MATIC_X_ADDRESS).approve(TRANSFER_STRATEGY_ADDRESS, 60000 *1e18);
```
target - address of Emission Manager.

3. Configure the Liquidity Mining emissions on the Emission Manager contract.
withDelegateCall - has to always be false. Otherwise, the Payloads controller won't have permission to configure LM.

```
EMISSION_MANAGER.configureAssets([{
accessLevel - has to always be PayloadsControllerUtils.AccessLevel.Level_1, reverts otherwise.

emissionPerSecond: 60000 * 1e18 / (180 days in seconds)
value - has to always be 0. Otherwise, the proposal won't be executable.

totalSupply: 0
string signature - has to always be empty.

distributionEnd: current timestamp + (180 days in seconds)
bytes callData - payload received on step 3.

});
```

asset: Aave Variable Debt Token of wMatic // 0x4a1c3aD6Ed28a636ee1751C69071f6be75DEb8B8
Below is an example with the pseudo-code to create a Liquidity Mining configuration proposal 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 check out this [test](./tests/PermissionedControllerEmissionTestMATICXPolygon.t.sol).

reward: MaticX Token address // 0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6
1. Make sure the Rewards Vault has a sufficient balance of the MaticX token.

transferStrategy: ITransferStrategyBase(STRATEGY_ADDRESS) // 0x53F57eAAD604307889D87b747Fc67ea9DE430B01
```
IERC20(MATIC_X_ADDRESS).balanceOf(REWARDS_VAULT) > 60000 *1e18
```

rewardOracle: IEACAggregatorProxy(MaticX_ORACLE_ADDRESS) // 0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403
2. Do an ERC-20 approval 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);
```

## How to modify emissions of the LM program?
3. Create a payload with the call of EMISSION_MANAGER.

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.
The emissions can be modified there, with the only requirement being that `sum(all-emissions) == TOTAL_DISTRIBUTION`
```
bytes memory payload = abi.encodeWithSelector(EMISSION_MANAGER.configureAssets.selector, [{

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.
emissionPerSecond: 60000 * 1e18 / (180 days in seconds)

_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._
totalSupply: 0

## How to configure emissions after the LM program has been created?
distributionEnd: current timestamp + (180 days in seconds)

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.
asset: Aave Variable Debt Token of wMatic // 0x4a1c3aD6Ed28a636ee1751C69071f6be75DEb8B8

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.
reward: MaticX Token address // 0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6

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.
transferStrategy: ITransferStrategyBase(STRATEGY_ADDRESS) // 0x53F57eAAD604307889D87b747Fc67ea9DE430B01

rewardOracle: IEACAggregatorProxy(MaticX_ORACLE_ADDRESS) // 0x5d37E4b374E6907de8Fc7fb33EE3b0af403C7403

}])
```

4. Submit a proposal in the Permissioned Payloads Controller with the Payloads Manager:

```
PERMISSIONED_PAYLOADS_CONTROLLER.createPayload([{

target: EMISSION_MANAGER,

withDelegateCall: false,

accessLevel: PayloadsControllerUtils.AccessControl.Level_1,

value: 0,

signature: "",

calldata: payload

}])
```

## How to update an existing LM program

The process to update the existing LM program is quite similar to the explained LM setup process. The difference from the previous process is that you need to use the `setDistributionEnd()` and `setEmissionPerSecond()` functions instead of the `configureAssets()` function of the Emission Manager. Payloads received after encoding calls of these functions in the same way need to be passed to the `createPayload()` function of the Permissioned Payloads Controller to create a proposal.

## Configuration tools

This repository includes a generator to help you bootstrap the required files for an emission configuration. To generate an LM configuration proposal, you need to run `npm run generate`. It can generate either LM setup or LM update proposal.

As a result you'll receive helper files similar to [PermissionedControllerEmissionTestMATICXPolygon](tests/PermissionedControllerEmissionTestMATICXPolygon.t.sol) and [PermissionedPayloadsControllerAndExecutorDeploy](scripts/EmissionMATICXPolygonConfigurationDeploy.s.sol). The first file is test file, it can help you to validate your configuration. Once the configuration is validated you can deploy your proposal using the second file. All required scripts you'll find inside these files.

To get a full list of available commands, run `npm run generate -- --help`.

## 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.
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 Payloads Manager to do it progressively as well, as the users accrue rewards over time.

- Can we configure mutiple rewards for the same asset?

Expand Down Expand Up @@ -127,13 +166,13 @@ Similarly you can also run the test via `forge test -vv` which will emit the sel

- 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.
Yes, the liquidity mining program could be stopped at any moment by the Payloads Manager.
The duration of the Liquidity Mining program could be increased as well, totally the choice of Payloads Manager.
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?
- Can we change the amount of liquidity mining rewards?

Yes, the liquidity mining rewards could be increased or decreased by the Emission Admin. To do so, please refer
Yes, the liquidity mining rewards could be increased or decreased. 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
Expand Down
3 changes: 2 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ script = 'scripts'
out = 'out'
libs = ['lib']
fs_permissions = [{access = "write", path = "./reports"}]
solc = '0.8.19'
solc = '0.8.20'
evm_version = 'shanghai'
no_match_path = "*.s.sol"

[rpc_endpoints]
mainnet = "${RPC_MAINNET}"
Expand Down
8 changes: 8 additions & 0 deletions generator/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ export function generateContractName(options: Options, pool?: PoolIdentifier) {
return name;
}

export function generateScriptName(options: Options, pool: PoolIdentifier) {
let name = `${pool}_`
name += `DeployPayload`;
name += `${options.shortName}`;
name += `_${options.date}`;
return name;
}

export function getChainAlias(chain) {
return chain === 'Ethereum' ? 'mainnet' : chain.toLowerCase();
}
Expand Down
Loading
Loading