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

Feat: add script to merge all proposal actions #641

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7052baf
feat: add proposals data folder to gitIgnore
clauBv23 Feb 6, 2025
01a99d4
feat: create script to merge the json actions
clauBv23 Feb 6, 2025
0903be1
feat: add update path in the hh config file
clauBv23 Feb 6, 2025
2583128
feat: create the proposal creation call information to the script
clauBv23 Feb 7, 2025
81ac811
feat: use the actions descriptions as proposal metadatat
clauBv23 Feb 7, 2025
09f3e4f
feat: add logic to stor the metadata on ipfs and set the cid on the p…
clauBv23 Feb 7, 2025
51da846
feat: add proposal information to the json generated
clauBv23 Feb 7, 2025
fa672a4
feat: update the script to get the proposal information properly from…
clauBv23 Feb 7, 2025
b198e13
feat: add direction regarding how to use the script
clauBv23 Feb 10, 2025
8b0b675
feat: add format when storing info in json
clauBv23 Feb 10, 2025
219b4af
feat: set the proposal end date in the future
clauBv23 Feb 10, 2025
6c13c30
feat: add test to check new deployment proposal is correct
clauBv23 Feb 10, 2025
d19a55e
fix typo
clauBv23 Feb 10, 2025
b361110
fix: un mark generate proposal json as async
clauBv23 Feb 10, 2025
34eba92
fix: revert if something went wrong when generating the jsons
clauBv23 Feb 10, 2025
38051ab
feat: validate json has all the needed info
clauBv23 Feb 10, 2025
398cc4e
fix: revert if something when wrong generating the calldata
clauBv23 Feb 10, 2025
542e416
fix: revert
clauBv23 Feb 10, 2025
037a082
fix: typo
clauBv23 Feb 10, 2025
88829cb
fix: throw if something went wrong
clauBv23 Feb 11, 2025
e02f64d
feat(wip): add function to check all stages after proposal execution
clauBv23 Feb 11, 2025
40076d2
Merge branch 'main' into feat/add-script-to-merge-all-proposal-actions
clauBv23 Feb 11, 2025
34ef747
feat: add check for the permission and plugin and framework state aft…
clauBv23 Feb 11, 2025
ca271e8
feat: store the json to avoid losing the deployed addresses
clauBv23 Feb 11, 2025
8aed2c6
fix: update ignored folder to the new one
clauBv23 Feb 12, 2025
8dd03b7
feat: add folder for the script and related files
clauBv23 Feb 12, 2025
fb39d88
fix: update script path and test paths, add filter for identifying ea…
clauBv23 Feb 12, 2025
5c8cc35
fix: uncomment function call
clauBv23 Feb 12, 2025
927eec3
fix: revert messages and add check for creating the file
clauBv23 Feb 12, 2025
cccd6af
feat: add readme describing how using the script
clauBv23 Feb 12, 2025
cc0d964
fix: modify upload to pinata function call to new one
clauBv23 Feb 12, 2025
f02921d
feat: bump sdk version
clauBv23 Feb 12, 2025
3c2fc95
update copy
Rekard0 Feb 28, 2025
0d4af0e
update the enddate
Rekard0 Feb 28, 2025
35015b4
Fixing the local test
brickpop Feb 28, 2025
51cffed
add conditional skip test
Rekard0 Feb 28, 2025
e339c95
don't require pinata in testing
Rekard0 Feb 28, 2025
83dd772
add comment
Rekard0 Feb 28, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ yarn-error.log*
deployments
deployed_contracts.json
managementDAOTX.json
packages/contracts/scripts/plugin-proposals-data/

# generated
generated
Expand Down
24 changes: 24 additions & 0 deletions packages/contracts/deploy/update/to_v1.4.0/01_Info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log('\nInfo: Updating to version 1.4.0');

hre.proposalInfo = {
proposalTitle: 'Upgrade OSx Protocol to version 1.4.0',
proposalSummary:
'Upgrade OSx Protocol to version 1.4.0, and release Admin Plugin v1.2, Multisig v1.3 and TokenVoting v1.3',
proposalResources: [
{
name: 'audit report',
url: 'https://github.com/aragon/osx/tree/main/audits',
},
],
// todo either adjust this values or configure them to get the correct ones from env or json
proposalStartDate: 0,
proposalEndDate: 1739096365,
};
};
export default func;
func.tags = ['Info', 'v1.4.0'];
func.dependencies = ['Env'];
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,16 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
}

const storeInfo = {
proposalInfo: hre.proposalInfo,
deployedContractAddresses,
managementDAOActions: hre.managementDAOActions,
};

await fs.writeFile('deployed_contracts.json', JSON.stringify(storeInfo));
await fs.writeFile(
'deployed_contracts.json',
JSON.stringify(storeInfo, null, 2),
'utf-8'
);
};
export default func;
func.tags = ['New', 'Conclude', 'ConcludeEnd'];
Expand Down
7 changes: 6 additions & 1 deletion packages/contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,12 @@ const config: HardhatUserConfig = {
gasPrice: 80000000000,
deploy: ENABLE_DEPLOY_TEST
? ['./deploy']
: ['./deploy/env', './deploy/new', './deploy/verification'],
: [
'./deploy/env',
'./deploy/new',
'./deploy/verification',
'./deploy/update',
],
},
localhost: {
deploy: ENABLE_DEPLOY_TEST
Expand Down
3 changes: 2 additions & 1 deletion packages/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"prepublishOnly": "yarn build && yarn build:npm",
"docgen": "hardhat docgen",
"docs": "DOCS=true scripts/prepare-docs.sh",
"clean": "rm -rf artifacts cache deployments typechain"
"clean": "rm -rf artifacts cache deployments typechain",
"generate-proposal": "ts-node scripts/generate-manaign-dao-proposal-info.ts"
},
"repository": {
"type": "git",
Expand Down
213 changes: 213 additions & 0 deletions packages/contracts/scripts/generate-manaign-dao-proposal-info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
// note using version 1.3.0 due to is the one currently installed on the managing dao change it once it's upgraded
import {Multisig__factory as Multisig_v1_3_0__factory} from '../typechain/@aragon/osx-v1.3.0/plugins/governance/multisig/Multisig.sol';
import {uploadToPinata} from '@aragon/osx-commons-sdk';
import {ethers} from 'ethers';
import * as fs from 'fs';
import * as path from 'path';

/**
* This script merges the plugin proposals actions inside the `proposalActionsPath` (./plugin-proposals-data) folder
* into the `mergedProposalActionsPath` (./merged-proposals.json) file.
*
* Steps
* 1- deploy all needed plugins
* 2- copy their deployment script to the `scripts/plugin-proposals-data` folder
* 3- deploy the new osx version (this can be done before deploy the plugins) => this will create a `deployed_contracts.json` file
* 4- run this script to merge the calldata from each plugin and the framework deployment into a single file
*/

interface Action {
to: string;
value: number;
data: string;
description: string;
}

interface ProposalAction {
to: string;
value: number;
data: string;
}

const deployedContractsPath = path.join(
__dirname,
'../deployed_contracts.json'
);
const proposalActionsPath = path.join(__dirname, './plugin-proposals-data');

const mergedProposalActionsPath = path.join(
__dirname,
'./merged-proposals.json'
);

const calldataPath = path.join(__dirname, './calldata.json');

async function generateProposalJson() {
try {
// check if the file exists
if (!fs.existsSync(deployedContractsPath)) {
console.error('deployed_contracts.json file not found');
return;
}

const deployedContractsRaw = fs.readFileSync(
deployedContractsPath,
'utf-8'
);
// load the osx deployed contracts
const deployedContracts = JSON.parse(deployedContractsRaw);

// creates the folder if it doesn't exist
if (!fs.existsSync(proposalActionsPath)) {
fs.mkdirSync(proposalActionsPath, {recursive: true});
console.error(
'plugin-proposals-data folder created, add plugin proposals json to merge them'
);
return;
}

// read the plugin proposals data
const proposalFiles = fs
.readdirSync(proposalActionsPath)
.filter(file => file.endsWith('.json'));

if (proposalFiles.length === 0) {
console.error('No plugin proposals found in plugin-proposals-data');
return;
}

// store each plugin action
let tmpAction: Action;
for (const file of proposalFiles) {
const filePath = path.join(proposalActionsPath, file);
const dataRaw = fs.readFileSync(filePath, 'utf-8');
const data = JSON.parse(dataRaw);

tmpAction = {
to: data.actions[0].to,
value: data.actions[0].value,
data: data.actions[0].data,
description: data.proposalDescription,
};

deployedContracts.managementDAOActions.push(tmpAction);
}

// write the updated JSON back to a new file
fs.writeFileSync(
mergedProposalActionsPath,
JSON.stringify(deployedContracts, null, 2),
'utf-8'
);

console.log(
`Successfully created merged-proposals.json with all proposal actions in ${mergedProposalActionsPath}!`
);
} catch (error) {
console.error('Error generating proposal JSON:', error);
return;
}
}

export function generateHexCalldataInJson(functionArgs: any[]) {
try {
const abi = Multisig_v1_3_0__factory.abi;
const iface = new ethers.utils.Interface(abi);

const calldata = iface.encodeFunctionData('createProposal', functionArgs);

const jsonOutput = {
functionName: 'createProposal',
functionArgs: functionArgs,
calldata: calldata,
};

// write the call information in the json file
fs.writeFileSync(
calldataPath,
JSON.stringify(jsonOutput, null, 2),
'utf-8'
);
console.log(
`Successfully created calldata.json with the function call information in ${calldataPath}!`
);
} catch (error) {
console.error('Error encoding function data:', error);
throw error;
}
}

async function main() {
generateProposalJson();

// get the actions to send it to the createHexCalldata function
const jsonFile = JSON.parse(
fs.readFileSync(mergedProposalActionsPath, 'utf-8')
);

let args = [];

if (!jsonFile.managementDAOActions) {
console.error('No actions found in merged-proposals.json');
return 1;
}
// remove the description from the actions
let proposalActions: ProposalAction[] = [];
let proposalMetadataFullDescription: string = '';
jsonFile.managementDAOActions.forEach((action: Action) => {
proposalActions.push({
to: action.to,
value: action.value,
data: action.data,
});
proposalMetadataFullDescription += action.description + ' ';
});

// this should be adjusted based on the actual proposal
if (!jsonFile.proposalInfo) {
console.error('No proposal info found in merged-proposals.json');
return 1;
}

const metadatata = {
title: jsonFile.proposalInfo.proposalTitle,
summary: jsonFile.proposalInfo.proposalSummary,
description: proposalMetadataFullDescription,
resources: jsonFile.proposalInfo.proposalResources,
};

const metadataCIDPath = await uploadToPinata(
JSON.stringify(metadatata, null, 2),
`management-dao-proposal-update-v1.4.0-metadata`
);

// push the metadata
args.push(ethers.utils.hexlify(ethers.utils.toUtf8Bytes(metadataCIDPath)));
// push the actions
args.push(proposalActions);

// push allow failure map => to zero
args.push(0);

// push approve proposal => to false
args.push(false);

// push try execution => to false
args.push(false);

// push the start and end dates
args.push(jsonFile.proposalInfo.proposalStartDate);
args.push(jsonFile.proposalInfo.proposalEndDate);

// generate the calldata in a json file
generateHexCalldataInJson(args);
}

main()
.then(() => {
console.log('done!');
})
.catch(error => {
console.error('Error in main:', error);
process.exit(1);
});
3 changes: 3 additions & 0 deletions packages/contracts/src/test/Migration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ import {PluginRepoRegistry as PluginRepoRegistry_v1_3_0} from "@aragon/osx-v1.3.
import {ENSSubdomainRegistrar as ENSSubdomainRegistrar_v1_0_0} from "@aragon/osx-v1.0.1/framework/utils/ens/ENSSubdomainRegistrar.sol";
import {ENSSubdomainRegistrar as ENSSubdomainRegistrar_v1_3_0} from "@aragon/osx-v1.3.0/framework/utils/ens/ENSSubdomainRegistrar.sol";

// needed in the script to generate the managing dao proposal when upgrading
import {Multisig as Multisig_v1_3_0} from "@aragon/osx-v1.3.0/plugins/governance/multisig/Multisig.sol";

// Integration Testing
import {ProxyFactory} from "@aragon/osx-commons-contracts/src/utils/deployment/ProxyFactory.sol";

Expand Down
10 changes: 10 additions & 0 deletions packages/contracts/types/hardhat.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ declare module 'hardhat/types/runtime' {
aragonToVerifyContracts: AragonVerifyEntry[];
managementDAOMultisigPluginAddress: string;
placeholderBuildCIDPath: string;
proposalInfo: {
proposalTitle: string;
proposalSummary: string;
proposalResources: {
name: string;
url: string;
}[];
proposalStartDate: number;
proposalEndDate: number;
};
managementDAOActions: {
to: string;
value: BigNumberish;
Expand Down
Loading