-
Notifications
You must be signed in to change notification settings - Fork 2
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
Add script to create auto payload #9
Open
Maltmark
wants to merge
3
commits into
main
Choose a base branch
from
proposal_name
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Script to generate proposal | ||
|
||
## How to use | ||
|
||
1. the script should be run from the local fork of aave-proposal repository | ||
2. in create_proposal_v3.py: | ||
a. Set the config JSON with the needed changes: | ||
example: | ||
|
||
``` | ||
config = { | ||
CHAIN: Chain.OPTIMISM, | ||
BLOCK_NUMBER_TO_TEST: 84619167, | ||
Action.RISK_PARAMS: [{ | ||
ASSET: "WBTC_UNDERLYING", | ||
DATA: {Field.LIQ_THRESHOLD: {VALUE: 7800, IS_CHANGED: True}, | ||
Field.LTV: {VALUE: 7300, IS_CHANGED: True}, | ||
Field.LIQ_BONUS: {VALUE: 10850, IS_CHANGED: True}, | ||
} | ||
}, | ||
{ | ||
ASSET: "DAI_UNDERLYING", | ||
DATA: {Field.LIQ_THRESHOLD: {VALUE: 8300, IS_CHANGED: True}, | ||
Field.LTV: {VALUE: 7800, IS_CHANGED: True}, | ||
Field.LIQ_BONUS: {VALUE: 10500, IS_CHANGED: False}, | ||
} | ||
},] | ||
|
||
} | ||
``` | ||
|
||
- CHAIN: the chain (support Optimism, Polygon, Mainnet, Arbitrum) | ||
- BLOCK_NUMBER_TO_TEST: block number to test the code (from last days) | ||
- Action.PARAMS: genral parameters to change - supported parameters: supply caps, borrow caps, borrowable isolation | ||
- Action.RISK_PARAMS: risk parameters to change (LTV, LT LB) | ||
- ASSET: the name of the asset as define in chain address book | ||
- DATA: JSON with 2 keys - value and is changed (if value was not change pass False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,284 @@ | ||
from abc import ABC, abstractmethod | ||
import os | ||
from payload_utils_v3 import * | ||
from git import Repo | ||
from datetime import datetime | ||
import calendar | ||
|
||
|
||
class CreateFile(ABC): | ||
def __init__(self, pr_name: str, paylaod_name: str, info: str, snapshot: str, discussion: str, config): | ||
self.chain = config[CHAIN] | ||
self.chain_name = CHAIN_CONFIG[self.chain]["name"] | ||
self.address_book = CHAIN_CONFIG[self.chain]["address_book"] | ||
self.paylaod_name = paylaod_name | ||
self.info = info | ||
self.pr_name = pr_name | ||
self.snapshot = snapshot | ||
self.discussion = discussion | ||
self.config = config | ||
|
||
def _create_file(self, is_test): | ||
self.set_up() | ||
data = self.get_data(is_test) | ||
code = self.get_code() | ||
tamplate = self.get_tamplate(data, code) | ||
path = self.get_path() | ||
file_name = self.get_file_name() | ||
if not os.path.exists(path): | ||
os.makedirs(path) | ||
with open(f'{path}/{file_name}', 'w') as f: | ||
print("Writing: ", tamplate) | ||
f.write(tamplate) | ||
|
||
def set_up(self): | ||
now = datetime.now() # current date and time | ||
month = int(now.strftime("%m")) | ||
day = now.strftime("%d") | ||
month_short_name = calendar.month_abbr[month] | ||
current_date = month_short_name + day | ||
self.current_name = self.paylaod_name + current_date | ||
|
||
def get_data(self, is_test): | ||
data_set_up = "" | ||
for asset_change in self.config.get(Action.PARAMS, []): | ||
data_set_up += self.get_all_params_data(asset_change[DATA], | ||
asset_change[ASSET], is_test) + "\n" | ||
for asset_change in self.config.get(Action.RISK_PARAMS, []): | ||
data_set_up += self.get_all_params_data(asset_change[DATA], | ||
asset_change[ASSET], is_test) + "\n" | ||
|
||
return data_set_up | ||
|
||
def get_all_params_data(self, asset_change_data, asset_name, is_test): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can u add types? |
||
data = "" | ||
for type in asset_change_data: | ||
data += self.get_param_data(type, | ||
asset_change_data, asset_name, is_test) | ||
return data | ||
|
||
def get_param_data(self, type, asset_change_data, asset_name, is_test=False): | ||
comment = "" | ||
if type in [Field.LIQ_THRESHOLD, Field.LTV, Field.LIQ_BONUS]: | ||
percent = int(asset_change_data[type][VALUE]) / 100 | ||
minus = 0 | ||
if type == Field.LIQ_BONUS: | ||
minus = 100 | ||
comment += f""" // {percent - minus}%""" | ||
if not asset_change_data[type].get(IS_CHANGED, True): | ||
|
||
if is_test: | ||
return "" | ||
comment += ' Not Changed' | ||
|
||
if type in asset_change_data: | ||
value = asset_change_data[type][VALUE] | ||
if isinstance(value, (bool)): | ||
instance_type = BOOL | ||
elif isinstance(value, (int)): | ||
instance_type = UINT | ||
return f""" {instance_type} {asset_name }_{type.name} = {str(value).lower()};""" + comment + "\n" | ||
return "" | ||
|
||
def get_code(self): | ||
code_change = "" | ||
for asset_change in self.config.get(Action.PARAMS, []): | ||
code_change += self.get_code_per_change( | ||
asset_change_data=asset_change[DATA], asset_name=asset_change[ASSET]) | ||
for asset_change in self.config.get(Action.RISK_PARAMS, []): | ||
code_change += self.get_code_per_risk_change( | ||
asset_change_data=asset_change[DATA], asset_name=asset_change[ASSET]) | ||
return code_change | ||
|
||
@abstractmethod | ||
def create_file(self): | ||
pass | ||
|
||
@abstractmethod | ||
def get_tamplate(self): | ||
pass | ||
|
||
@abstractmethod | ||
def get_path(self): | ||
pass | ||
|
||
@abstractmethod | ||
def get_code_per_change(self): | ||
pass | ||
|
||
@abstractmethod | ||
def get_code_per_risk_change(self, asset_change_data, asset_name): | ||
pass | ||
|
||
@abstractmethod | ||
def get_file_name(self): | ||
pass | ||
|
||
|
||
class CreateContractFile(CreateFile): | ||
|
||
def create_file(self): | ||
return self._create_file(False) | ||
|
||
def get_tamplate(self, data, code): | ||
return f"""// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.16; | ||
import {{IProposalGenericExecutor}} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; | ||
import {{{self.address_book}, {self.address_book}Assets}} from 'aave-address-book/{self.address_book}.sol'; | ||
|
||
/** | ||
* @dev {self.info} | ||
{"* - Snapshot: "+ self.snapshot if self.snapshot else ""} | ||
{"* - Discussion: "+ self.discussion if self.discussion else ""} | ||
*/ | ||
contract {self.current_name} is IProposalGenericExecutor {{ | ||
{data} | ||
function execute() external {{ | ||
{code} | ||
}} | ||
}} | ||
""" | ||
|
||
def get_path(self): | ||
return f'src/contracts/{self.chain_name}/' | ||
|
||
def get_file_name(self): | ||
return f'{self.current_name}.sol' | ||
|
||
def get_code_per_change(self, asset_change_data, asset_name): | ||
data_change = "" | ||
for type in asset_change_data: | ||
data_change += self.set_param_change(type, | ||
asset_change_data, asset_name) + "\n" | ||
return data_change | ||
|
||
def set_param_change(self, cap_type, asset_change_data, asset_name): | ||
if cap_type in asset_change_data: | ||
return f""" {self.address_book}.POOL_CONFIGURATOR.{FIELD_TO_CHANGE_NAME_MAP[cap_type]}({self.address_book}Assets.{asset_name}, {asset_name}_{cap_type.name});""" | ||
return "" | ||
|
||
def get_code_per_risk_change(self, asset_change_data, asset_name): | ||
return f""" {self.address_book}.POOL_CONFIGURATOR.configureReserveAsCollateral( | ||
{self.address_book}Assets.{asset_name}, | ||
{asset_name}_{Field.LTV.name}, | ||
{asset_name}_{Field.LIQ_THRESHOLD.name}, | ||
{asset_name}_{Field.LIQ_BONUS.name} | ||
); \n""" | ||
|
||
|
||
class CreateContractTestFile(CreateFile): | ||
|
||
def create_file(self): | ||
self._create_file(True) | ||
|
||
def get_tamplate(self, data, code): | ||
pool = f"{self.address_book}.POOL" | ||
return f"""// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.16; | ||
|
||
import 'forge-std/Test.sol'; | ||
|
||
import {{{self.address_book}, {self.address_book}Assets}} from 'aave-address-book/{self.address_book}.sol'; | ||
import {{{self.current_name}}} from '../../../{self.get_contract_path()}{self.current_name}.sol'; | ||
import {{TestWithExecutor}} from 'aave-helpers/GovHelpers.sol'; | ||
import {{AaveGovernanceV2}} from 'aave-address-book/AaveGovernanceV2.sol'; | ||
import {{ProtocolV3TestBase, ReserveConfig}} from 'aave-helpers/ProtocolV3TestBase.sol'; | ||
|
||
contract {self.current_name}Test is ProtocolV3TestBase, TestWithExecutor {{ | ||
{data} | ||
function setUp() public {{ | ||
vm.createSelectFork(vm.rpcUrl('{self.chain_name}'), { | ||
self.config[BLOCK_NUMBER_TO_TEST]}); | ||
_selectPayloadExecutor({CHAIN_CONFIG[self.chain]["executor"]}); | ||
|
||
}} | ||
|
||
function testPayload() public {{ | ||
{self.current_name} proposalPayload = new {self.current_name}(); | ||
|
||
ReserveConfig[] memory allConfigsBefore = _getReservesConfigs({pool}); | ||
|
||
// execute payload | ||
_executePayload(address(proposalPayload)); | ||
|
||
//Verify payload: | ||
ReserveConfig[] memory allConfigsAfter = _getReservesConfigs({pool}); | ||
{code} | ||
}} | ||
}} | ||
""" | ||
|
||
def get_contract_path(self): | ||
return f'src/contracts/{self.chain_name}/' | ||
|
||
def get_path(self): | ||
return f'src/test/{self.chain_name}/' | ||
|
||
def get_file_name(self): | ||
return f'{self.current_name}Test.t.sol' | ||
|
||
def get_code_per_change(self, asset_change_data, asset_name): | ||
config_name = f"{asset_name}_CONFIG" | ||
asset_check = f""" | ||
|
||
ReserveConfig memory {config_name} = ProtocolV3TestBase._findReserveConfig( | ||
allConfigsBefore, | ||
{self.address_book}Assets.{asset_name} | ||
); | ||
""" | ||
for field in asset_change_data.keys(): | ||
if asset_change_data[field].get(IS_CHANGED, True): | ||
asset_check += f""" | ||
{config_name}.{FIELD_TO_ASSERT_NAME_MAP[field]} = {asset_name}_{field.name};""" + "\n" | ||
|
||
asset_check += f""" | ||
ProtocolV3TestBase._validateReserveConfig({config_name}, allConfigsAfter);""" + "\n" | ||
return asset_check | ||
|
||
def get_code_per_risk_change(self, asset_change_data, asset_name): | ||
return self.get_code_per_change(asset_change_data, asset_name) | ||
|
||
|
||
def set_up_repo(proposal_name): | ||
repo_path = os.getenv(GIT_REPO_PATH) | ||
repo = Repo(repo_path) | ||
current = repo.create_head(proposal_name) | ||
current.checkout() | ||
# master = repo.heads.master | ||
# repo.git.pull('origin', master) | ||
build = "make build" | ||
print("run command: ", build) | ||
os.system(build) | ||
return repo, current | ||
|
||
|
||
def commit_and_create_pr(repo, current, pr_name): | ||
if repo.index.diff(None) or repo.untracked_files: | ||
|
||
repo.git.add(A=True) | ||
print('git add') | ||
repo.git.commit(m=pr_name) | ||
print('git commit') | ||
|
||
repo.git.push('--set-upstream', 'origin', current) | ||
print('git push') | ||
else: | ||
print('no changes') | ||
|
||
|
||
def create_proposal_pr(pr_name, proposal_name, payload_info, snapshot_link, discussion_link, config, to_push=False): | ||
repo, current = set_up_repo(proposal_name) | ||
create = CreateContractFile( | ||
pr_name, proposal_name, payload_info, snapshot_link, discussion_link, config) | ||
createTest = CreateContractTestFile( | ||
pr_name, proposal_name, payload_info, snapshot_link, discussion_link, config) | ||
|
||
create.create_file() | ||
createTest.create_file() | ||
|
||
run_test = f"forge test -vvv --match-contract {create.current_name}Test" | ||
print("run command: ", run_test) | ||
os.system(run_test) | ||
|
||
if to_push: | ||
commit_and_create_pr(repo, current, pr_name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from re import T | ||
from create_class import * | ||
|
||
config = { | ||
CHAIN: Chain.OPTIMISM, | ||
BLOCK_NUMBER_TO_TEST: 84619167, | ||
Action.RISK_PARAMS: [{ | ||
ASSET: "WBTC_UNDERLYING", | ||
DATA: {Field.LIQ_THRESHOLD: {VALUE: 7800, IS_CHANGED: True}, | ||
Field.LTV: {VALUE: 7300, IS_CHANGED: True}, | ||
Field.LIQ_BONUS: {VALUE: 10850, IS_CHANGED: True}, | ||
} | ||
}, | ||
{ | ||
ASSET: "DAI_UNDERLYING", | ||
DATA: {Field.LIQ_THRESHOLD: {VALUE: 8300, IS_CHANGED: True}, | ||
Field.LTV: {VALUE: 7800, IS_CHANGED: True}, | ||
Field.LIQ_BONUS: {VALUE: 10500, IS_CHANGED: False}, | ||
} | ||
},] | ||
|
||
} | ||
|
||
|
||
pr_name = "Chaos Labs change WBTC and DAI risk params Optimism" | ||
proposal_name = "AaveV3OptiRiskParmas" | ||
payload_info = "This proposal change WBTC and DAI risk params" | ||
snapshot_link = None | ||
discussion_link = "https://governance.aave.com/t/arfc-chaos-labs-risk-parameter-updates-aave-v3-optimism-2023-03-22/12421" | ||
|
||
|
||
create_proposal_pr(pr_name, proposal_name, payload_info, | ||
snapshot_link, discussion_link, config, True) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we define type for config, even TypeDict