diff --git a/packages/contracts/README.adoc b/packages/contracts/README.adoc deleted file mode 100644 index 6888f5a78..000000000 --- a/packages/contracts/README.adoc +++ /dev/null @@ -1,32 +0,0 @@ -= OSX - -This is the reference guide of the link:https://github.com/aragon/osx[osx contracts] package. - -== Core - -{{DAO}} - -{{IDAO}} - -{{PermissionManager}} - -{{CallbackHandler}} - -== Factories - -{{DAOFactory}} - -{{PluginRepoFactory}} - - -== Registries - -{{DAORegistry}} - -{{PluginRepoRegistry}} - -== Framework - -{{PluginRepo}} - -{{PluginSetupProcessor}} diff --git a/packages/contracts/deployed_contracts_detailed.json b/packages/contracts/deployed_contracts_detailed.json new file mode 100644 index 000000000..92f374165 --- /dev/null +++ b/packages/contracts/deployed_contracts_detailed.json @@ -0,0 +1,182 @@ +{ + "ManagementDAOImplementation": { + "address": "0xa9186cf932e4e05b4606d107361Ae7b6651AF1b7", + "blockNumber": 6049593, + "deploymentTx": "0xae998dc65cca7ab1515843e6dbb31f21e4f38fe807c72a5f914ece15d7745a01" + }, + "ManagementDAOProxy": { + "address": "0x31a46feD168ECb9DE7d87E543Ba2e8DD101ad0a0", + "blockNumber": 6049594, + "deploymentTx": "0xa21d873add9f4267d6fd250ec52adaa5d90d5a7a9223af8133eebbcfbc499a13" + }, + "ENSRegistry": { + "address": "0x977E2F3aA628f7676d685A3AFe2df48c51C9949a", + "blockNumber": 6049597, + "deploymentTx": "0x7d6c46444c8c2483f55d2fe8dff3391daaddf19a54e314db3a4ee1f66cda228f" + }, + "PublicResolver": { + "address": "0x8647AC3a1270c746130418010A368449d1944A82", + "blockNumber": 6049598, + "deploymentTx": "0x38d3dc91ae9a15baa917ab47eb783e0687c54b567b7d42211b64b17fc63ba7fd" + }, + "DAOENSSubdomainRegistrarImplementation": { + "address": "0x98B0fE54Eddb752290Dd87a02402fb0728d05445", + "blockNumber": 6049606, + "deploymentTx": "0x213e2994a82562e5dbdb170fb866c7f800982d5e341ec6aa80af39d41e06d562" + }, + "DAOENSSubdomainRegistrarProxy": { + "address": "0x5BEE4b1691cBEDab1B08726f49D914d9bBC3Dd74", + "blockNumber": 6049607, + "deploymentTx": "0xd982714ff10f6d9a306c79e48082c352e5f1b54da525fedec2e2cc22d45ea5b3" + }, + "PluginENSSubdomainRegistrarImplementation": { + "address": "0x99D34Ab8f2cC1e05722345Bc3baa4E78cC6e0a14", + "blockNumber": 6049608, + "deploymentTx": "0x6cd287fab4dd75ea991ec6717b78363fac0bd7700737177ebf75610a227fadaf" + }, + "PluginENSSubdomainRegistrarProxy": { + "address": "0xe38293134297f062Eb9aB7d7CDa83733357C90c1", + "blockNumber": 6049609, + "deploymentTx": "0xfcdd2a5e9e1053cadf90d93fe74a20beb4275c07d68c9d5e11c94d6a213f187e" + }, + "DAORegistryImplementation": { + "address": "0xDF8340475A4a8490C763B88f7e88179Ec0DfaC1C", + "blockNumber": 6049611, + "deploymentTx": "0x8468c680db5d65adfe5868c52175a5c304aad1c6f4d469d8a72f184cc1ec07f2" + }, + "DAORegistryProxy": { + "address": "0x7BF3cF1176C4a037d3Ea2a5FF3d480359aC65Ecd", + "blockNumber": 6049612, + "deploymentTx": "0xd61b4a5df4557bfe154f85108094e7abc108c3e2fc9f24e408cdd680e85a0c5e" + }, + "PluginRepoRegistryImplementation": { + "address": "0xC4f7eE5ECE62e6bB53cad7a734b7539eFcbDCCbD", + "blockNumber": 6049613, + "deploymentTx": "0xf7b6b12ef3b0866570a4dbf5433ca2a4c8644fa9ffde82cf626d1cdae8c9750d" + }, + "PluginRepoRegistryProxy": { + "address": "0xC35EBbbFeB1c7C17295Ba6EB08F59cC1e54d2c7d", + "blockNumber": 6049614, + "deploymentTx": "0xf2ce026e50e29498288dbd2ad11927dd7e8c2eebf301fd30c0d151af966790b3" + }, + "PluginRepoFactory": { + "address": "0x2557627d61F85E5629b23B48d7226D0a9368D507", + "blockNumber": 6049615, + "deploymentTx": "0xfffd61156da1bd2025474958a7a2632c84bccff4e536acb9b3a2b58b9db03f25" + }, + "PluginRepoBase": { + "address": "0xbDe9768478f4DcD74aD37c709c8AaE1d1339F799", + "blockNumber": 6049615, + "deploymentTx": "0xfffd61156da1bd2025474958a7a2632c84bccff4e536acb9b3a2b58b9db03f25" + }, + "PluginSetupProcessor": { + "address": "0x62D1e5b65c5D345c4aA967F172f686f581c0614E", + "blockNumber": 6049616, + "deploymentTx": "0xafd38673baa677fb580a803013e6983846bc8eae8d27f4cbb94197128a683172" + }, + "DAOFactory": { + "address": "0xe390BF14A5623479E9bd0e3559D98B6fab44251F", + "blockNumber": 6049617, + "deploymentTx": "0x4bd45b014a05b588bcbd848197ba05fcc1923c21d9ca13c6fad53b489f84fcd2" + }, + "DAOBase": { + "address": "0x2f727C19D578e8Cb781aeaD6dEb3828F283F1D65", + "blockNumber": 6049617, + "deploymentTx": "0x4bd45b014a05b588bcbd848197ba05fcc1923c21d9ca13c6fad53b489f84fcd2" + }, + "AddresslistVotingSetup": { + "address": "0xaf981B8FB5429d1D64B16F98A2BDfc6cF667A08D", + "blockNumber": 6049621, + "deploymentTx": "0x21d9b668b6096b925a7084899d2e303987f63a9d29a77f2a1fb26158668ad574" + }, + "AddresslistVotingSetupImplementation": { + "address": "0xA3Db89b12604eb893b6A3AbbC6113dC667dB3630", + "blockNumber": 6049621, + "deploymentTx": "0x21d9b668b6096b925a7084899d2e303987f63a9d29a77f2a1fb26158668ad574" + }, + "GovernanceERC20": { + "address": "0x2135b360D32B17fAEE573BDE47C75e5e34bdC875", + "blockNumber": 6049622, + "deploymentTx": "0x8d45733f9e12d4ff18845481efe7d389837eaafc3fd2f74c48165a2c94cca57c" + }, + "GovernanceWrappedERC20": { + "address": "0x32A1A43203c93600555C200104D21c3584ED1A28", + "blockNumber": 6049623, + "deploymentTx": "0xf38510e3e8d5c3a3df4531ed7292ac02bcead4a092f55dade2abe4f54e0fe46c" + }, + "TokenVotingSetup": { + "address": "0x54A8E10751B030aB6a6bC508eD6d0634947774dd", + "blockNumber": 6049624, + "deploymentTx": "0xe940c7fc67a3820763d0080a1605bc01c030606a918fa67b21d2af7d0f2ffd08" + }, + "TokenVotingSetupImplementation": { + "address": "0x310cfdD99178A12147a78cC0E5efD285F6227f31", + "blockNumber": 6049624, + "deploymentTx": "0xe940c7fc67a3820763d0080a1605bc01c030606a918fa67b21d2af7d0f2ffd08" + }, + "AdminSetup": { + "address": "0x065B89D4726664BAb42EFc916c24660EAd0427DB", + "blockNumber": 6049625, + "deploymentTx": "0x7846bc39cbca9f96b4276b70450654e09f1a8fb04061460c92677341902727e7" + }, + "AdminSetupImplementation": { + "address": "0xc2246A415432de3774D794a14b699B02b6323ce2", + "blockNumber": 6049625, + "deploymentTx": "0x7846bc39cbca9f96b4276b70450654e09f1a8fb04061460c92677341902727e7" + }, + "MultisigSetup": { + "address": "0xFeA08d5ff36E99CEEb9627789d726D78D1E91B73", + "blockNumber": 6049626, + "deploymentTx": "0xa63f3f2be9a99981a74e686290b330ad1d2b6f8421dd54dd91934923be3e706b" + }, + "MultisigSetupImplementation": { + "address": "0xf4cc2F15515386743a04EF97dd0389A35203F1a4", + "blockNumber": 6049626, + "deploymentTx": "0xa63f3f2be9a99981a74e686290b330ad1d2b6f8421dd54dd91934923be3e706b" + }, + "PlaceholderSetup": { + "address": "0x60ccEaBCAaA362e90d0D75bcbEE125D43A51D191", + "blockNumber": 6049627, + "deploymentTx": "0x758afc83070f924a25656436106eb92947315af3b7c6a7f27b5d2aac622bfb94" + }, + "AddressListVotingRepoProxy": { + "address": "0x6B372Ad885C9Ae94Ac626f651347c472ad58F01e", + "blockNumber": 6049628, + "deploymentTx": "0xa9df78087990828e8df515b377efe9e31b12e102773cd81c1bcf98092518955a" + }, + "AddressListVotingRepoImplementation": { + "address": "0xbDe9768478f4DcD74aD37c709c8AaE1d1339F799", + "blockNumber": 6049615, + "deploymentTx": "0xfffd61156da1bd2025474958a7a2632c84bccff4e536acb9b3a2b58b9db03f25" + }, + "TokenVotingRepoProxy": { + "address": "0x7c340b278f11F456Bb1a2AAF48d87f8D28Ee46a1", + "blockNumber": 6049631, + "deploymentTx": "0x8d351e692a90a3ca3e33cc4c8b9e499643483d2199203e42e8e77644842a1eca" + }, + "TokenVotingRepoImplementation": { + "address": "0xbDe9768478f4DcD74aD37c709c8AaE1d1339F799", + "blockNumber": 6049615, + "deploymentTx": "0xfffd61156da1bd2025474958a7a2632c84bccff4e536acb9b3a2b58b9db03f25" + }, + "AdminRepoProxy": { + "address": "0x4DD52163dB9340D255b9267dc254252DB320b2c2", + "blockNumber": 6049634, + "deploymentTx": "0x991f9912c5791ee06e281751ed54b0e605198ac156672de1e5fafa5c29ba45fd" + }, + "AdminRepoImplementation": { + "address": "0xbDe9768478f4DcD74aD37c709c8AaE1d1339F799", + "blockNumber": 6049615, + "deploymentTx": "0xfffd61156da1bd2025474958a7a2632c84bccff4e536acb9b3a2b58b9db03f25" + }, + "MultisigRepoProxy": { + "address": "0xf32B2C0094B9ecb7FC64C0CCB58a8bEc796055B5", + "blockNumber": 6049636, + "deploymentTx": "0x3c817bf37f0bf3a317380bcf8d4b8d4d0efc3f79f09ea6c909248618fc5c4fd1" + }, + "MultisigRepoImplementation": { + "address": "0xbDe9768478f4DcD74aD37c709c8AaE1d1339F799", + "blockNumber": 6049615, + "deploymentTx": "0xfffd61156da1bd2025474958a7a2632c84bccff4e536acb9b3a2b58b9db03f25" + } +} \ No newline at end of file diff --git a/packages/contracts/docs/config.js b/packages/contracts/docs/config.js index 302962b9b..4afb34bc1 100644 --- a/packages/contracts/docs/config.js +++ b/packages/contracts/docs/config.js @@ -1,13 +1,16 @@ const path = require('path'); const fs = require('fs'); -const {version, repository} = require('../package.json'); +const { version, repository } = require('../package.json'); const helpers = require(path.resolve(__dirname, './templates/helpers')); // overwrite the functions. helpers.version = () => version; helpers.githubURI = () => repository.url; +helpers.readmePath = (opts) => { + return 'src/' + opts.data.root.id.replace(/\.adoc$/, '') + '/README.adoc'; +}; /** @type import('solidity-docgen/dist/config').UserConfig */ module.exports = { @@ -17,6 +20,13 @@ module.exports = { pageExtension: '.adoc', collapseNewlines: true, pages: (_, file, config) => { - return 'osx-contracts' + config.pageExtension; + const sourcesDir = path.resolve(config.root, config.sourcesDir); + let dir = path.resolve(config.root, file.absolutePath); + while (dir.startsWith(sourcesDir)) { + dir = path.dirname(dir); + if (fs.existsSync(path.join(dir, 'README.adoc'))) { + return path.relative(sourcesDir, dir) + config.pageExtension; + } + } }, }; diff --git a/packages/contracts/docs/modules/ROOT/images/aragon-os-framework-overview.drawio.svg b/packages/contracts/docs/modules/ROOT/images/aragon-os-framework-overview.drawio.svg new file mode 100644 index 000000000..e101a296f --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/images/aragon-os-framework-overview.drawio.svg @@ -0,0 +1,51 @@ +
External
+ External +
Code Layer
+ Code Layer +
- decide strategy
+ - decide strategy +
- set parameters
- manage permissions
+ - set parameters... +
-create DAOs
-manage plugins

+ - create DAOs... +
- providebasicand
customfunctionalities
+ - provide basic and... +
Responsibilities
+ Responsibilities +
- provide secure
primitives

+ - provide secure... +
Aragon OSx
+ Aragon OSx +
Governance Layer
+ Governance Layer +
governs
+ governs +
Aragon OSx
Framework DAO
+ Aragon OSx... +
governs
+ governs +
Aragon DAO
+ Aragon DAO +
manages / deploys
+ manages / deploys +
OpenZeppelin Contracts
+ OpenZeppelin... +
uses
+ uses +
Core
+ Core +
DAO
+ DAO +
Plugin
+ Plugin +
Framework
+ Framework +
DAO Creation
+ DAO Creation +
Plugin
Management
+ Plugin... +

ENS

+ ENS +
+ Text is not SVG - cannot display +
\ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/images/aragon-os-infrastructure-core-overview.drawio.svg b/packages/contracts/docs/modules/ROOT/images/aragon-os-infrastructure-core-overview.drawio.svg new file mode 100644 index 000000000..562f5051f --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/images/aragon-os-infrastructure-core-overview.drawio.svg @@ -0,0 +1,89 @@ +
Framework
+ Framework +
Plugin Management
+ Plugin Management +
DAO Creation
+ DAO Creation +
Core
+ Core +
Plugin
+ Plugin +
IPlugin
+ IPlugin +
DAO
+ DAO +
PermissionManager
+ PermissionManager +
CallbackHandler
+ CallbackHandler +
DaoAuthorizable
+ DaoAuthorizable +
PluginRepo
Registry
+ PluginRepo... +
versions
+ versions +
PluginRepo
+ PluginRepo +
processes
+ processes +
PluginSetup
Procesor
+ PluginSetup... +
registers
+ registers +
creates & manages
+ creates & manages +
PluginSetup
+ PluginSetup +
PluginRepoFactory
+ PluginRepoFactory +
registers
+ registers +
👷
+ 👷 +
Non-upgradeable
+ Non-upgradeable +
Upgradeable
+ Upgradeable +
DaoAuthorizable
Upgradeable
+ DaoAuthorizable... +
connects
+ connects +
ERC-1271
SignatureValidator
+ ERC-1271... +
select Plugins
+ select Plugins +
creates
+ creates +
creates
+ creates +
DAOFactory
+ DAOFactory +
DAORegistry
+ DAORegistry +
creates
+ creates +
PluginCloneable
+ PluginCloneable +
Plugin
+ Plugin +
PluginUUPS Upgradeable
+ PluginUUPS Upgradeab... +
Creation
+ Creation +
Curation
+ Curation +
Setup
+ Setup +
IMembeship
+ IMembeship +
IProposal
+ IProposal +
ERC-4824
DAO Interface
+ ERC-4824... +
provides
data
+ provides... +
Upgradeable
+ Upgradeable +
+ Text is not SVG - cannot display +
\ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/images/dao-plugin.drawio.svg b/packages/contracts/docs/modules/ROOT/images/dao-plugin.drawio.svg new file mode 100644 index 000000000..c4d8f137e --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/images/dao-plugin.drawio.svg @@ -0,0 +1,33 @@ +
DAO
+ DAO +
execute()
+ execute() +
Token Voting
Plugin
+ Token Voting... +
Permission
Manager
+ Permission... +
createProposal()
+ createProposal() +

🧑‍💼

+ 🧑‍💼 +
changeSettings()
+ changeSettings() +
🧑‍🔧
+ 🧑‍🔧 +
DeFi
Plugin
+ DeFi... +
hasPermission()
+ hasPermission() +
invest()
+ invest() +
🧑‍🌾
+ 🧑‍🌾 +
depositTokens()
+ depositTokens() +

🛡

+ 🛡 +
external contract
+ external cont... +
+ Text is not SVG - cannot display +
\ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/images/plugin-installation.drawio.svg b/packages/contracts/docs/modules/ROOT/images/plugin-installation.drawio.svg new file mode 100644 index 000000000..d25b34465 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/images/plugin-installation.drawio.svg @@ -0,0 +1,447 @@ + + + + + + + + +
+
+
+ + 1c. + + createProposal() +
+
+
+
+ + 1c. createProposal() + +
+
+ + + + +
+
+
+ Plugin Repository +
+
+
+
+ + Plugin Repository + +
+
+ + + + + + +
+
+
+ + 1b. + + + prepareInstallation() + +
+
+
+
+ + 1b. prepareInstallation() + +
+
+ + + + +
+
+
+ DAO +
+
+
+
+ + DAO + +
+
+ + + + + + + + +
+
+
+ doSomething() ✨ +
+
+
+
+ + doSomething() ✨ + +
+
+ + + + + +
+
+
+ Plugin Logic +
+
+
+
+ + Plugin Logic + +
+
+ + + + + + + + +
+
+
+ + 1a. + + prepareInstallation(repo, version) +
+
+
+
+ + 1a. prepareInstallation(repo, version) + +
+
+ + + + + +
+
+
+ + + 2c. + + grant() + +
+
+
+
+ + 2c. grant() + +
+
+ + + + +
+
+
+ Permission +
+ Manager +
+
+
+
+ + Permission... + +
+
+ + + + +
+
+
+ Plugin +
+
+
+
+ + Plugin + +
+
+ + + + +
+
+
+ 1.2 +
+
+
+
+ + 1.2 + +
+
+ + + + +
+
+
+ + 1.1 +
+
+
+
+
+
+ + 1.1 + +
+
+ + + + +
+
+
+ 1.2 +
+
+
+
+ + 1.2 + +
+
+ + + + + + +
+
+
+ + + 2a. + + + execute() + + +
+
+
+
+ + 2a. execute() + +
+
+ + + + + + +
+
+
+
+ + + + Proposal + + : + + +
+
+ + + grant permissions + + +
+
+
+
+
+ + Proposal:... + +
+
+ + + + + + +
+
+
+ + + 2b. + + applyInstallation() + +
+
+
+
+ + 2b. applyInstallation() + +
+
+ + + + +
+
+
+ Plugin Setup Processor +
+
+
+
+ + Plugin Setup Process... + +
+
+ + + + +
+
+
+ Plugin Setup +
+
+
+
+ + Plugin Setup + +
+
+ + + + +
+
+
+ + 🗳 + +
+
+
+
+ + 🗳 + +
+
+ + + + + +
+
+
+ + 🧑‍🔧 + +
+
+
+
+ + 🧑‍🔧 + +
+
+ + + +
+
+
+ + Proposal +
+ Creator +
+
+
+
+
+
+ + Proposal... + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/images/plugin-repo-overview.drawio.svg b/packages/contracts/docs/modules/ROOT/images/plugin-repo-overview.drawio.svg new file mode 100644 index 000000000..ab6bba1fe --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/images/plugin-repo-overview.drawio.svg @@ -0,0 +1,41 @@ +
PluginRepoRegistry
+ PluginRepoRegistry +
0x54...
+ 0x54... +
PluginRepo
ENS name
+ PluginRepo... +
1.2
+ 1.2 +
1.3
+ 1.3 +
2.1
+ 2.1 +
...
+ ... +
1.1
+ 1.1 +
0xf2...
+ 0xf2... +
0x1a...
+ 0x1a... +
...
+ ... +
Version
+ Version +
Plugin
+ Plugin +
PluginSetup
+ PluginSetup +
1.1
+ 1.1 +
Metadata
+ Metadata +
Tag
+ Tag +
Build
+ Build +
Release
+ Release +
+ Text is not SVG - cannot display +
\ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/images/plugin-uninstallation.drawio.svg b/packages/contracts/docs/modules/ROOT/images/plugin-uninstallation.drawio.svg new file mode 100644 index 000000000..dfb2ef572 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/images/plugin-uninstallation.drawio.svg @@ -0,0 +1,468 @@ + + + + + + + + + +
+
+
+ + doSomething() + +
+
+
+
+ + doSomething() + +
+
+ + + + +
+
+
+ Plugin Repository +
+
+
+
+ + Plugin Repository + +
+
+ + + + +
+
+
+ DAO +
+
+
+
+ + DAO + +
+
+ + + + + + + +
+
+
+ Plugin Logic +
+
+
+
+ + Plugin Logic + +
+
+ + + + + + + + +
+
+
+ + 1a. + + prepareUninstallation(repo, version) +
+
+
+
+ + 1a. prepareUninstallation(repo, version) + +
+
+ + + + + +
+
+
+ + + 2c. + + revoke() + +
+
+
+
+ + 2c. revoke() + +
+
+ + + + +
+
+
+ Permission +
+ Manager +
+
+
+
+ + Permission... + +
+
+ + + + +
+
+
+ Plugin +
+
+
+
+ + Plugin + +
+
+ + + + +
+
+
+ 1.2 +
+
+
+
+ + 1.2 + +
+
+ + + + +
+
+
+ + 1.1 + +
+
+
+
+ + 1.1 + +
+
+ + + + +
+
+
+ 1.2 +
+
+
+
+ + 1.2 + +
+
+ + + + + + + +
+
+
+ + + 2a. + + + execute() + + +
+
+
+
+ + 2a. execute() + +
+
+ + + + + + +
+
+
+ + 1c. + + createProposal() +
+
+
+
+ + 1c. createProposal() + +
+
+ + + + + + +
+
+
+
+ + + + Proposal + + : + + +
+
+ + + revoke permissions + + +
+
+
+
+
+ + Proposal:... + +
+
+ + + + + + +
+
+
+ + + 2b. + + applyUninstallation() + +
+
+
+
+ + 2b. applyUninstallation() + +
+
+ + + + +
+
+
+ Plugin Setup Processor +
+
+
+
+ + Plugin Setup Process... + +
+
+ + + + +
+
+
+ + ✂️ + +
+
+
+
+ + ✂️ + +
+
+ + + + +
+
+
+ Plugin Setup +
+
+
+
+ + Plugin Setup + +
+
+ + + + + + + +
+
+
+ + 🗳 + +
+
+
+
+ + 🗳 + +
+
+ + + + +
+
+
+ + 🧑‍🔧 + +
+
+
+
+ + 🧑‍🔧 + +
+
+ + + +
+
+
+ + Proposal +
+ Creator +
+
+
+
+
+
+ + Proposal... + +
+
+ + + +
+
+
+ + 1b. + + + prepareUnnstallation() + +
+
+
+
+ + 1b. prepareUnnstallation() + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/images/plugin-update.drawio.svg b/packages/contracts/docs/modules/ROOT/images/plugin-update.drawio.svg new file mode 100644 index 000000000..e92a3b128 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/images/plugin-update.drawio.svg @@ -0,0 +1,523 @@ + + + + + + + + + +
+
+
+ doSomething() +
+
+
+
+ + doSomething() + +
+
+ + + + + +
+
+
+ doSomethingNew() ✨ +
+
+
+
+ + doSomethingNew() ✨ + +
+
+ + + + +
+
+
+ Plugin +
+
+
+
+ + Plugin + +
+
+ + + + +
+
+
+ Plugin Repository +
+
+
+
+ + Plugin Repository + +
+
+ + + + +
+
+
+ DAO +
+
+
+
+ + DAO + +
+
+ + + + + + +
+
+
+ + 2a. + + + execute() + +
+
+
+
+ + 2a. execute() + +
+
+ + + + + + + +
+
+
+ + + 2c. + + grant/revoke() + +
+
+
+
+ + 2c. grant/revoke() + +
+
+ + + + +
+
+
+ Permission +
+ Manager +
+
+
+
+ + Permission... + +
+
+ + + + + + +
+
+
+ + + 2b. + + applyUpdate() + +
+
+
+
+ + 2b. applyUpdate() + +
+
+ + + + + + +
+
+
+ + 1c. + + createProposal() +
+
+
+
+ + 1c. createProposal() + +
+
+ + + + + + +
+
+
+
+ + + + Proposal + + : + + +
+
+ + + modify permissions + + +
+
+
+
+
+ + Proposal:... + +
+
+ + + + + + +
+
+
+ + 1.2 + +
+
+
+
+ + 1.2 + +
+
+ + + + +
+
+
+ 1.3 +
+
+
+
+ + 1.3 + +
+
+ + + + + + + + +
+
+
+ Plugin Logic +
+
+
+
+ + Plugin Logic + +
+
+ + + + + + + + +
+
+
+ Plugin Setup +
+
+
+
+ + Plugin Setup + +
+
+ + + + +
+
+
+ + 1.1 + +
+
+
+
+ + 1.1 + +
+
+ + + + +
+
+
+ + 1.2 + +
+
+
+
+ + 1.2 + +
+
+ + + + +
+
+
+ 1.3 +
+
+
+
+ + 1.3 + +
+
+ + + + + +
+
+
+ + 1a. + + prepareUpdate(plugin, newVersion) +
+
+
+
+ + 1a. prepareUpdate(plugin, newVersion) + +
+
+ + + + +
+
+
+ Plugin Setup Processor +
+
+
+
+ + Plugin Setup Process... + +
+
+ + + + +
+
+
+ + ✨ + +
+
+
+
+ + ✨ + +
+
+ + + + +
+
+
+ + 🗳 + +
+
+
+
+ + 🗳 + +
+
+ + + + + +
+
+
+ + 🧑‍🔧 + +
+
+
+
+ + 🧑‍🔧 + +
+
+ + + +
+
+
+ + Proposal +
+ Creator +
+
+
+
+
+
+ + Proposal... + +
+
+ + + +
+
+
+ + 1b. + + + prepareUpdate() + +
+
+
+
+ + 1b. prepareUpdate() + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/images/plugin-version.drawio.svg b/packages/contracts/docs/modules/ROOT/images/plugin-version.drawio.svg new file mode 100644 index 000000000..d6d314aae --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/images/plugin-version.drawio.svg @@ -0,0 +1,19 @@ +
Version
+ Version +
Plugin
+ Plugin +
PluginSetup
+ PluginSetup +
1.1
+ 1.1 +
Metadata
+ Metadata +
Tag
+ Tag +
Build
+ Build +
Release
+ Release +
+ Text is not SVG - cannot display +
\ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/images/what_is_a_plugin.png b/packages/contracts/docs/modules/ROOT/images/what_is_a_plugin.png new file mode 100644 index 000000000..4144ed615 Binary files /dev/null and b/packages/contracts/docs/modules/ROOT/images/what_is_a_plugin.png differ diff --git a/packages/contracts/docs/modules/ROOT/nav.adoc b/packages/contracts/docs/modules/ROOT/nav.adoc index 01d50a6be..e96fb54c6 100644 --- a/packages/contracts/docs/modules/ROOT/nav.adoc +++ b/packages/contracts/docs/modules/ROOT/nav.adoc @@ -1,51 +1,29 @@ * xref:index.adoc[Overview] -* xref:how-it-works/index.adoc[How it works] -** xref:how-it-works/core/index.adoc[Smart Contracts] -*** xref:how-it-works/core/dao/index.adoc[DAO] -**** xref:how-it-works/core/dao/actions.adoc[Advanced DAO Actions] -*** xref:how-it-works/core/permissions/index.adoc[Permissions] -**** xref:how-it-works/core/permissions/conditions.adoc[Permission Conditions] -*** xref:how-it-works/core/plugins/index.adoc[Plugins] - -** xref:how-it-works/framework/index.adoc[Framework] - -*** xref:how-it-works/framework/dao-creation/index.adoc[Creating a DAO] - -*** xref:how-it-works/framework/plugin-management/index.adoc[Plugins] -**** xref:how-it-works/framework/plugin-management/plugin-repo/index.adoc[Plugin Repositories] -***** xref:how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.adoc[Publishing a Plugin] -**** xref:how-it-works/framework/plugin-management/plugin-setup/index.adoc[Installing Plugins] -***** xref:how-it-works/framework/plugin-management/plugin-setup/security-risk-mitigation.adoc[Plugin Security and Risks] - -*** xref:how-it-works/framework/ens-names.adoc[ENS Names] - -** xref:how-it-works/framework-dao.adoc[Protocol Governance] - -* xref:how-to-guides/index.adoc[Tutorials] -** xref:how-to-guides/dao/index.adoc[Operating a DAO] -*** xref:how-to-guides/dao/best-practices.adoc[Best Practices] -*** xref:how-to-guides/dao/action-execution.adoc[Executing Actions on behalf of the DAO] -*** xref:how-to-guides/dao/protocol-upgrades.adoc[Upgrade your DAO to future Aragon OSX versions] -*** xref:how-to-guides/dao/managing-plugins.adoc[Managing your DAO's Plugins] - -** xref:how-to-guides/plugin-development/index.adoc[Developing a Plugin] -*** xref:how-to-guides/plugin-development/best-practices.adoc[Before Starting] -*** xref:how-to-guides/plugin-development/plugin-types.adoc[Choosing The Plugin Type] -*** xref:how-to-guides/plugin-development/non-upgradeable-plugin/index.adoc[Non-Upgradeable Plugins] -**** xref:how-to-guides/plugin-development/non-upgradeable-plugin/initialization.adoc[Initialization] -**** xref:how-to-guides/plugin-development/non-upgradeable-plugin/implementation.adoc[Plugin Implementation Contract] -**** xref:how-to-guides/plugin-development/non-upgradeable-plugin/setup.adoc[Plugin Setup Contract] -*** xref:how-to-guides/plugin-development/upgradeable-plugin/index.adoc[Upgradeable Plugins] -**** xref:how-to-guides/plugin-development/upgradeable-plugin/initialization.adoc[Initialization] -**** xref:how-to-guides/plugin-development/upgradeable-plugin/implementation.adoc[Plugin Implementation Contract] -**** xref:how-to-guides/plugin-development/upgradeable-plugin/setup.adoc[Plugin Setup Contract] -**** xref:how-to-guides/plugin-development/upgradeable-plugin/subsequent-builds.adoc[Subsequent Builds] -**** xref:how-to-guides/plugin-development/upgradeable-plugin/updating-versions.adoc[Upgrade a DAO Plugin] -*** xref:how-to-guides/plugin-development/governance-plugins/index.adoc[Governance Plugins] -**** xref:how-to-guides/plugin-development/governance-plugins/proposals.adoc[Proposal] -**** xref:how-to-guides/plugin-development/governance-plugins/membership.adoc[Membership] -*** xref:how-to-guides/plugin-development/meta-tx-plugins.adoc[Meta Transactions] -*** xref:how-to-guides/plugin-development/publication/index.adoc[Publication of your plugin into Aragon OSx] -**** xref:how-to-guides/plugin-development/publication/versioning.adoc[New Plugin Version] -**** xref:how-to-guides/plugin-development/publication/metadata.adoc[Plugin Metadata] - +* xref:core/index.adoc[Core] +** xref:core/dao.adoc[DAO] +** xref:core/plugins.adoc[Plugins] +** xref:core/permissions.adoc[Permissions] +** xref:core/actions.adoc[Actions] + +* xref:framework/index.adoc[Framework] +** xref:framework/dao-factory-registry.adoc[DAO Factory & Registry] +** xref:framework/plugin-repos.adoc[Plugin Repositories] +** xref:framework/repo-factory-registry.adoc[PluginRepo Factory & Registry] +** xref:framework/plugin-setup-processor.adoc[Plugin Setup Processor] +** xref:framework/ens-registrar.adoc[ENS Registrar] + +* xref:guide-set-up-dao/index.adoc[Guide: Setting up a DAO] +** xref:guide-set-up-dao/execute-actions.adoc[Executing actions] +** xref:guide-set-up-dao/manage-dao-plugins.adoc[Managing your DAO's plugins] +** xref:guide-set-up-dao/custom-permission-condition.adoc[Writing custom permission conditions] +** xref:guide-set-up-dao/upgrade-dao.adoc[Upgrading your DAO] +** xref:guide-set-up-dao/keep-dao-safe.adoc[Keeping your DAO safe] + +* xref:guide-develop-plugin/index.adoc[Guide: Developing a plugin] +** xref:guide-develop-plugin/design-your-plugin.adoc[Designing your plugin] +** xref:guide-develop-plugin/write-plugin-contract.adoc[Writing your plugin contract] +** xref:guide-develop-plugin/write-plugin-setup-contract.adoc[Writing your plugin setup contract] +** xref:guide-develop-plugin/write-upgradeable-plugin.adoc[Writing your upgradeable plugin] +** xref:guide-develop-plugin/upgrade-plugin.adoc[Upgrading your plugin] +** xref:guide-develop-plugin/follow-best-practices.adoc[Following best practices] +** xref:guide-develop-plugin/publishing-plugin.adoc[Publishing your plugin] \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/dao/actions.adoc b/packages/contracts/docs/modules/ROOT/pages/core/actions.adoc similarity index 95% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/core/dao/actions.adoc rename to packages/contracts/docs/modules/ROOT/pages/core/actions.adoc index 59c7e7cd2..dc5cd5784 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/dao/actions.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/core/actions.adoc @@ -1,4 +1,4 @@ -= Advanced DAO Actions += Actions & Execution == A Deep Dive into Actions and Execution @@ -44,7 +44,7 @@ Actions can be - external services (e.g. Uniswap, Compound, etc.) - Aragon OSx plugins (e.g., the DAO can be a member of a multisig installed in another DAO), - - Aragon OSx protocol infrastructure (e.g., to xref:how-it-works/framework/plugin-management/plugin-setup/index.adoc[setup a plugin]). + - Aragon OSx protocol infrastructure (e.g., to xref:framework/plugin-setup-processor.adoc[setup a plugin]). - transfers of native tokens @@ -66,7 +66,7 @@ dao().execute({_callId: '', _actions: actions, _allowFailureMap: 0}); ``` -For the `execute` call to work, the caller must have the required xref:how-it-works/core/permissions/index.adoc[`EXECUTE_PERMISSION_ID` permission] on the DAO contract. +For the `execute` call to work, the caller must have the required xref:core/permissions.adoc[`EXECUTE_PERMISSION_ID` permission] on the DAO contract. ### The Action Array diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/dao/index.adoc b/packages/contracts/docs/modules/ROOT/pages/core/dao.adoc similarity index 86% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/core/dao/index.adoc rename to packages/contracts/docs/modules/ROOT/pages/core/dao.adoc index e4e1a0347..efff0fc38 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/dao/index.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/core/dao.adoc @@ -10,9 +10,9 @@ The `DAO` contract is the identity and basis of your organization. It is the add The most important and basic functionality of your DAO is the **execution of arbitrary actions**, which allows you to execute the DAO's own functions as well as interacting with the rest of the world, i.e., calling methods in other contracts and sending assets to other addresses. -NOTE: Typically, actions are scheduled in a proposal in a governance - xref:how-it-works/core/plugins/index.adoc[plugin installed to your DAO] +NOTE: Typically, actions are scheduled in a proposal in a governance - xref:core/plugins.adoc[plugin installed to your DAO] -Multiple `Action` structs can be put into one `Action[]` array and executed in a single transaction via the `execute` function. To learn more about actions and advanced features of the DAO executor, visit the xref:how-it-works/core/dao/actions.adoc[A Deep Dive Into Actions]. +Multiple `Action` structs can be put into one `Action[]` array and executed in a single transaction via the `execute` function. To learn more about actions and advanced features of the DAO executor, visit the xref:core/actions.adoc[A Deep Dive Into Actions]. ### 2. Asset Management @@ -24,11 +24,11 @@ The DAO provides basic **asset management** functionality to deposit, withdraw, - link:https://eips.ethereum.org/EIPS/eip-1155[ERC-1155 (Multi Token Standard)] tokens in the treasury. -In the future, more advanced asset management and finance functionality can be added to your DAO in the form of xref:how-it-works/core/plugins/index.adoc[plugins]. +In the future, more advanced asset management and finance functionality can be added to your DAO in the form of xref:core/plugins.adoc[plugins]. ### 3. Upgradeability -Your DAO contract has the ability to be upgraded to a newer version (see xref:how-to-guides/dao/protocol-upgrades.adoc[Upgrade your DAO]) if a new version of Aragon OSx is released in the future. These upgrades allow your DAO to smoothly transition to a new protocol version unlocking new features. +Your DAO contract has the ability to be upgraded to a newer version (see xref:guide-develop-plugin/upgrade-plugin.adoc[Upgrade your DAO]) if a new version of Aragon OSx is released in the future. These upgrades allow your DAO to smoothly transition to a new protocol version unlocking new features. ### 4. Callback Handling @@ -48,6 +48,6 @@ By supporting the link:https://eips.ethereum.org/EIPS/eip-721[ERC-721 (NFT Stand ### 6. Permission Management Lastly, it is essential that only the right entities (e.g., the DAO itself or trusted addresses) have permission to use the above-mentioned functionalities. This is why Aragon OSx DAOs contain a flexible and battle-tested **permission manager** being able to assign permissions for the above functionalities to specific addresses. -Although possible, the permissions to execute arbitrary actions or upgrade the DAO should not be given to EOAs as this poses a security risk to the organization if the account is compromised or acts adversarial. Instead, the permissions for the above-mentioned functionalities are better restricted to the `DAO` contract itself and triggered through governance xref:how-it-works/core/plugins/index.adoc[plugins] that you can install on your DAO. +Although possible, the permissions to execute arbitrary actions or upgrade the DAO should not be given to EOAs as this poses a security risk to the organization if the account is compromised or acts adversarial. Instead, the permissions for the above-mentioned functionalities are better restricted to the `DAO` contract itself and triggered through governance xref:core/plugins.adoc[plugins] that you can install on your DAO. -To learn more, visit the xref:how-it-works/core/permissions/index.adoc[permission manager] section. \ No newline at end of file +To learn more, visit the xref:core/permissions.adoc[permission manager] section. \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/index.adoc b/packages/contracts/docs/modules/ROOT/pages/core/index.adoc similarity index 85% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/core/index.adoc rename to packages/contracts/docs/modules/ROOT/pages/core/index.adoc index a9f074a53..93435f810 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/index.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/core/index.adoc @@ -24,13 +24,14 @@ In a nutshell, your Aragon OSx DAO consists of three pieces: The underlying smart contracts constitute **the core contracts** of the Aragon OSx DAO framework. -image::../../../_/images/optimized-svg/plugins/dao-plugin.drawio.svg[align="center"] +image::dao-plugin.drawio.svg[align="center"] An exemplary DAO setup showing interactions between the three core contract pieces triggered by different user groups: The `DAO` contract in blue containing the `PermissionManager` in red, respectively, as well as two `Plugin` contracts in green. Function calls are visualized as black arrows and require permission checks (red, dashed arrow). In this example, the permission manager determines whether the token voting plugin can execute actions on the DAO, a member can change its settings, or if a DeFi-related plugin is allowed to invest in a certain, external contract. In the upcoming sections, you will learn about each of them in more depth. -- xref:how-it-works/core/dao/index.adoc[The DAO Contract: The Identity and Basis of Your Organization] -- xref:how-it-works/core/permissions/index.adoc[Permissions: Managing Your DAO] -- xref:how-it-works/core/plugins/index.adoc[Plugins: Customizing your DAO] +// reorder if the nav bar is updated +- xref:core/dao.adoc[The DAO Contract: The Identity and Basis of Your Organization] +- xref:core/plugins.adoc[Plugins: Customizing your DAO] +- xref:core/permissions.adoc[Permissions: Managing Your DAO] \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/permissions/index.adoc b/packages/contracts/docs/modules/ROOT/pages/core/permissions.adoc similarity index 89% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/core/permissions/index.adoc rename to packages/contracts/docs/modules/ROOT/pages/core/permissions.adoc index 27801ca96..dffef9f15 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/permissions/index.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/core/permissions.adoc @@ -83,12 +83,15 @@ function grant( To prevent these functions from being called by any address, they are themselves permissioned via the `auth` modifier and require the caller to have the `ROOT_PERMISSION_ID` permission in order to call them. -NOTE: Typically, the `ROOT_PERMISSION_ID` permission is granted only to the `DAO` contract itself. Contracts related to the Aragon infrastructure temporarily require it during the xref:how-it-works/framework/dao-creation/index.adoc[DAO creation] and xref:how-it-works/framework/plugin-management/plugin-setup/index.adoc[plugin setup] processes. +[NOTE] +==== +Typically, the `ROOT_PERMISSION_ID` permission is granted only to the `DAO` contract itself. Contracts related to the Aragon infrastructure temporarily require it during the xref:framework/dao-factory-registry.adoc[DAO creation] and xref:framework/plugin-setup-processor.adoc[plugin setup] processes. This means, that these functions can only be called through the DAO’s `execute` function that, in turn, requires the calling address to have the `EXECUTE_PERMISSION_ID` permission. +==== -Typically, the `EXECUTE_PERMISSION_ID` permission is granted to governance contracts (such as a majority voting plugin owned by the DAO or a multi-sig). Accordingly, a proposal is often required to change permissions. -Exceptions are, again, the xref:how-it-works/framework/dao-creation/index.adoc[DAO creation] and xref:how-it-works/framework/plugin-management/plugin-setup/index.adoc[plugin setup] processes. +NOTE: Typically, the `EXECUTE_PERMISSION_ID` permission is granted to governance contracts (such as a majority voting plugin owned by the DAO or a multi-sig). Accordingly, a proposal is often required to change permissions. +Exceptions are, again, the xref:framework/dao-factory-registry.adoc[DAO creation] and xref:framework/plugin-setup-processor.adoc[plugin setup] processes. #### Granting Permission with Conditions @@ -105,9 +108,9 @@ function grantWithCondition( and specifying the `_condition` contract address. This provides full flexibility to customize the conditions under which the function call is allowed. -Typically, conditions are written specifically for and installed together with xref:how-it-works/core/plugins/index.adoc[plugins] +Typically, conditions are written specifically for and installed together with xref:core/plugins.adoc[plugins] -To learn more about this advanced topic and possible applications, visit the xref:how-it-works/core/permissions/conditions.adoc[permission conditions]. +To learn more about this advanced topic and possible applications, visit the xref:guide-set-up-dao/custom-permission-condition.adoc[permission conditions]. #### Granting Permission to `ANY_ADDR` @@ -127,7 +130,7 @@ By granting the `USE_PERMISSION_ID` to `_who: ANY_ADDR` on the contract `_where: Granting a permission with `_where: ANY_ADDR` to a condition has the effect that is granted on every contract. This is useful if you want to give an address `_who` permission over a large set of contracts that would be too costly or too much work to be granted on a per-contract basis. Imagine, for example, that many instances of the `Service` contract exist, and a user should have the permission to use all of them. By granting the `USE_PERMISSION_ID` with `_where: ANY_ADDR`, to some user `_who: userAddr`, the user has access to all of them. If this should not be possible anymore, you can later revoke the permission. -However, some restrictions apply. For security reasons, Aragon OSx does not allow you to use both, `_where: ANY_ADDR` and `_who: ANY_ADDR` in the same permission. Furthermore, the permission IDs of [permissions native to the `DAO` Contract](#permissions-native-to-the-dao-contract) cannot be used. +However, some restrictions apply. For security reasons, Aragon OSx does not allow you to use both, `_where: ANY_ADDR` and `_who: ANY_ADDR` in the same permission. Furthermore, the permission IDs of xref:#permissions_native_to_the_dao_contract[permissions native to the `DAO` Contract] cannot be used. Moreover, if a condition is set, we return its `isGranted` result and do not fall back to a more generic one. The condition checks occur in the following order 1. Condition with specific `_who` and specific `where`. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/plugins/index.adoc b/packages/contracts/docs/modules/ROOT/pages/core/plugins.adoc similarity index 90% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/core/plugins/index.adoc rename to packages/contracts/docs/modules/ROOT/pages/core/plugins.adoc index 9a901edbe..7c3711a95 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/plugins/index.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/core/plugins.adoc @@ -21,7 +21,7 @@ Whenever a DAO installs a plugin, an instance of that plugin's base template is Each instance of a plugin is installed to a DAO through the granting of permissions. -TIP: Learn more about the different xref:how-to-guides/plugin-development/plugin-types.adoc[plugin types] in our How-to guide. +TIP: Learn more about the different xref:guide-develop-plugin/design-your-plugin.adoc[plugin types] in our How-to guide. This raises questions on how the DAO manages plugins and who actually owns plugins. @@ -33,12 +33,12 @@ A DAO manages plugins and interactions between them. In more detail, its permiss - authorizes calls to plugin functions carrying the `auth` modifier - authorizes calls to DAO functions, for example the `execute` function, allowing to act as the DAO -image::../../../../_/images/optimized-svg/plugins/dao-plugin.drawio.svg[align="center"] +image::dao-plugin.drawio.svg[align="center"] An exemplary DAO setup showing interactions between the three core contract pieces triggered by different user groups: The `DAO` contract in blue containing the `PermissionManager` in red, respectively, as well as two `Plugin` contracts in green. Function calls are visualized as black arrows and require permission checks (red, dashed arrow). In this example, the permission manager determines whether the token voting plugin can execute actions on the DAO, a member can change its settings, or if a DeFi-related plugin is allowed to invest in a certain, external contract. Whereas deployed plugin instances belong to the DAO, the developer of the original plugin implementation owns the implementation -and setup contract of the plugin. The plugin developer is the maintainer of an Aragon OSx xref:how-it-works/framework/plugin-management/plugin-repo/index.adoc[plugin repo]. +and setup contract of the plugin. The plugin developer is the maintainer of an Aragon OSx xref:framework/plugin-repos.adoc[plugin repo]. Finally, the Aragon OSx protocol manages the registry in which the plugin repositories are listed, which is required to install a plugin using the Aragon OSx framework infrastructure to your DAO. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/dao-creation/index.adoc b/packages/contracts/docs/modules/ROOT/pages/framework/dao-factory-registry.adoc similarity index 66% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/dao-creation/index.adoc rename to packages/contracts/docs/modules/ROOT/pages/framework/dao-factory-registry.adoc index 527c50cc8..cd4015c78 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/dao-creation/index.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/framework/dao-factory-registry.adoc @@ -4,9 +4,8 @@ Two framework contracts manage the `DAO` contract creation process: -- The TODO:GIORGI [`DAOFactory`](../../../03-reference-guide/framework/dao/DAOFactory.md) -- The TODO:GIORGI [`DAORegistry`](../../../03-reference-guide/framework/dao/DAORegistry.md). - +- The xref:api:framework.adoc#DAOFactory[DAOFactory] +- The xref:api:framework.adoc#DAORegistry[DAORegistry] ### `DAOFactory` @@ -25,11 +24,11 @@ The `DAOFactory` create the `DAO` in four steps and interacts with the `DAORegis 2. Registers the new contract in the [`DAORegistry`](#daoregistry). TODO:GIORGI -3. Installs the plugins using the `PluginSetupProcessor` (see also the section about xref:how-it-works/framework/plugin-management/plugin-setup/index.adoc[the plugin setup process]). +3. Installs the plugins using the `PluginSetupProcessor` (see also the section about xref:framework/plugin-setup-processor.adoc[the plugin setup process]). -4. Sets the xref:how-it-works/core/permissions/index.adoc##permissions-native-to-the-dao-contract[native permissions] of the `DAO` and revokes its own ownership. +4. Sets the xref:core/permissions.adoc#permissions_native_to_the_dao_contract[native permissions] of the `DAO` and revokes its own ownership. -For more details visit the [`DAOFactory` reference guide entry](../../../03-reference-guide/framework/dao/DAOFactory.md). TODO: GIORGI +For more details visit the xref:api:framework.adoc#DAOFactory[`DAOFactory` reference guide entry]. ### `DAORegistry` @@ -45,8 +44,8 @@ function register( requiring the `REGISTER_DAO_PERMISSION_ID` permission currently held only by the `DAOFactory`. -If the requested ENS `subdomain` name xref:how-it-works/framework/ens-names.md[is valid] and not taken, the `DAORegistry` registers the subdomain and adds the `DAO` contract address to the `DAORegistry`. +If the requested ENS `subdomain` name xref:framework/ens-registrar.adoc[is valid] and not taken, the `DAORegistry` registers the subdomain and adds the `DAO` contract address to the `DAORegistry`. If the `subdomain` parameter is non-empty (not `""`) and still available, the ENS name will be registered. If the registration was successful, the DAO name, contract and creator addresses are emitted in an event. -For more details visit the [`DAORegistry` reference guide entry](../../../03-reference-guide/framework/dao/DAORegistry.md). TODO:GIORGI +For more details visit the xref:api:framework.adoc#DAORegistry[`DAORegistry` reference guide entry]. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/ens-names.adoc b/packages/contracts/docs/modules/ROOT/pages/framework/ens-registrar.adoc similarity index 55% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/ens-names.adoc rename to packages/contracts/docs/modules/ROOT/pages/framework/ens-registrar.adoc index 27d823cf9..2054a15dd 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/ens-names.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/framework/ens-registrar.adoc @@ -3,9 +3,9 @@ == Unique DAO and Plugin Repo Names To make DAOs and plugin repositories easily identifiable in the Aragon OSx ecosystem, we assign unique ENS names to them upon -registration during the xref:how-it-works/framework/dao-creation/index.adoc[DAO creation] and xref:how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.md[plugin publishing] processes. +registration during the xref:framework/dao-factory-registry.adoc[DAO creation] and xref:framework/repo-factory-registry.adoc[plugin publishing] processes. -TIP: You can skip registering an ENS name for your DAO under the `dao.eth` by leaving the TODO:GIORGI [`DAOSettings.subdomain` field](../../03-reference-guide/framework/dao/DAOFactory.md#public-struct-daosettings) empty when calling the [`createDao`](../../03-reference-guide/framework/dao/DAOFactory.md#external-function-createdao) function. +TIP: You can skip registering an ENS name for your DAO under the `dao.eth` by leaving the xref:api:framework.adoc#DAOFactory[`DAOSettings.subdomain` field] empty when calling the xref:api:framework.adoc#DAOFactory[`createDao`] function. ### Allowed Character Set diff --git a/packages/contracts/docs/modules/ROOT/pages/framework/index.adoc b/packages/contracts/docs/modules/ROOT/pages/framework/index.adoc new file mode 100644 index 000000000..e12aa1d05 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/framework/index.adoc @@ -0,0 +1,16 @@ + += Framework +== The Infrastructure Running the Aragon OSx Protocol + +The Aragon OSx protocol is composed of **framework-related contracts** creating and managing the **core contracts**. This includes the + +- xref:framework/dao-factory-registry.adoc[Creation of DAOs]and initial plugin configuration. +- xref:framework/repo-factory-registry.adoc[Creation of plugins] and the versioning of different implementations and respective setup contracts. +- xref:framework/plugin-setup-processor.adoc[Installation of plugins] and setting it up on the DAO. +- xref:framework/ens-registrar.adoc[Assignment of ENS Names] to `Plugin` and `DAO` contracts created through the framework. + +An overview of the framework and core contracts of the Aragon OSx protocol and their interactions is shown below: + +image::../../../../_/images/optimized-svg/framework/aragon-os-infrastructure-core-overview.drawio.svg[ align="center"] + +In the following sections, you will learn more about the framework-related contracts of the Aragon OSx protocol. \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/framework/plugin-repos.adoc b/packages/contracts/docs/modules/ROOT/pages/framework/plugin-repos.adoc new file mode 100644 index 000000000..fe38176f0 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/framework/plugin-repos.adoc @@ -0,0 +1,99 @@ += Plugin Repositories + +== Plugins + +As mentioned earlier, plugins built by Aragon and third-party developers can be added and removed from your DAO to adapt it to your needs. + +The management of these plugins is handled for you by the Aragon OSx protocol so that the process of + +- Releasing new plugins as well as +- Installing, updating, and uninstalling them to your DAO + +becomes as streamlined as possible. + +In the following, we learn what a plugin consists of. + +// + +### What Does a Plugin Consist Of? + +An Aragon OSx Plugin consists of: + +* The `PluginSetup` contract + ** referencing the `Plugin` implementation internally + ** containing the setup instruction to install, update, and uninstall it to an existing DAO + +* A metadata URI pointing to a `JSON` file containing the + ** AragonApp frontend information + ** Information needed for the setup ABI + +* A version tag consisting of a + ** Release number + ** Build number + +A detailed explanation of the xref:guide-develop-plugin/publishing-plugin.adoc#how_to_add_a_new_version_of_your_plugin[build and release versioning] is found in the Guides sections in our developer portal. + +.A schematic depiction of a plugin bundle consisting of a version tag, the plugin setup contract pointing to the plugin implementation contract, and a metadata URI. +image::../../../../_/images/optimized-svg/plugins/plugin-version.drawio.svg[align="center"] + + +The `PluginSetup` is written by you, the plugin developer. The processing of the setup is managed by the `PluginSetupProcessor`, the central component of the setup process in the Aragon OSx framework, which is explained in the section xref:framework/repo-factory-registry.adoc[The Plugin Setup Process]. + +Each plugin with its different builds and releases is versioned inside its own plugin repositories in a `PluginRepo` contract, which is explained in the next section. + + +== Plugin Repositories + + +### What are Plugin Repositories? + + +Each plugin has its own Plugin Repository, unique ENS name, and on-chain repository contract, the `PluginRepo`, in which different versions of the plugin are stored for reference using version tags constituted by a **release** and **build** number. + +Different versions might contain: + +- bug fixes +- new features +- breaking changes + +`PluginRepo` contracts themselves, each associated with a different plugin, are registered in the Aragon OSx `PluginRepoRegistry` and carry their own xref:framework/ens-registrar.adoc[ENS name] that the creator chooses. The xref:framework/repo-factory-registry.adoc#the_pluginreporegistry_contract[`PluginRepoRegistry` contract] is described in the upcoming subsection. + + +.Schematic depiction of the versioning taking place in the PluginRepoRegistry. +image::../../../../_/images/optimized-svg/plugins/plugin-repo-overview.drawio.svg[align="center"] + +Overview of the plugin versioning and registry in the Aragon OSx protocol. The `PluginRepoRegistry` contract, which is a curated list of ENS named `PluginRepo` contracts, is shown on the left. Each `PluginRepo` contract maintains a list of versions of the `PluginSetup` contract (internally referencing the `Plugin` implementation contract) and the associated UI building blocks as a URI, exemplarily shown on the right. + + +#### The `PluginRepo` Contract + +The `PluginRepo` contract versions the releases of a `Plugin`. The first version of a plugin is always published as release 1 and build 1 (version tag `1.1`). +When you publish the first plugin version, a new plugin repository is automatically created for you by the Aragon OSx protocol in which you +are the maintainer. The creation process is described in the xref:framework/repo-factory-registry.adoc[plugin repo creation process] section. + +The `PluginRepo` contract is link:https://eips.ethereum.org/EIPS/eip-1822[UUPS upgradeable], inherits from the xref:core/permissions.adoc[`PermissionManager`] and allows the maintainer of the repository to create new versions with the `createVersion` function: + +```solidity title="@aragon/framework/repo/PluginRepo.sol" +/// @notice Creates a new plugin version as the latest build for an existing release number or the first build for a new release number for the provided `PluginSetup` contract address and metadata. +/// @param _release The release number. +/// @param _pluginSetupAddress The address of the plugin setup contract. +/// @param _buildMetadata The build metadata URI. +/// @param _releaseMetadata The release metadata URI. +function createVersion( + uint8 _release, + address _pluginSetup, + bytes calldata _buildMetadata, + bytes calldata _releaseMetadata +) external auth(address(this), MAINTAINER_PERMISSION_ID); +``` + +The function receives four input arguments: + +1. The `_release` number to create the build for. If the release number exists already (e.g., release `1`), it is registered as the latest build (e.g., `1.3` if the previous build was `1.2`). +If it is a new release number, the build number is `1` (e.g., `2.1`). +2. The address of `PluginSetup` contract internally referencing the implementation contract (to copy, proxy, or clone from it) and taking care of xref:framework/plugin-setup-processor.adoc[installing, updating to, and uninstalling] this specific version. +3. The `_buildMetadata` URI pointing to a JSON file containing the UI data, setup data, and change description for this specific version. +4. The `_releaseMetadata` URI pointing to a JSON file containing the plugin name, description, as well as optional data such as images to be shown in the aragonApp frontend. + +Other functions present in the contract allow you to query previous versions and to update the release metadata. For more details visit the xref:api:framework.adoc#PluginRepo[`PluginRepo` reference guide entry]. +The `PluginRepo` is created for you when you publish the `PluginSetup` contract of your first version to the Aragon OSx protocol, which is explained in the next section: xref:framework/repo-factory-registry.adoc[The Plugin Repo Creation Process]. \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-setup/index.adoc b/packages/contracts/docs/modules/ROOT/pages/framework/plugin-setup-processor.adoc similarity index 61% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-setup/index.adoc rename to packages/contracts/docs/modules/ROOT/pages/framework/plugin-setup-processor.adoc index 9c77c5bb0..a38e0208d 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-setup/index.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/framework/plugin-setup-processor.adoc @@ -1,47 +1,38 @@ -= Installing Plugins += Plugin Setup Processor -== The Smart Contracts Behind Plugins +== Installing Plugins + +### The Smart Contracts Behind Plugins A DAO can be set up and customized by the **installation, update, and uninstallation** of plugins. Plugins are composed of two key contracts: - **Plugin contract:** contains the plugin's implementation logic; everything needed to extend the functionality for DAOs. - **Plugin Setup contract:** contains the instructions needed to install, update, and uninstall the plugin into the DAO. This is done through granting or revoking permissions, enabling plugins to perform actions within the scope of the DAO. - -image::../../../../../_/images/img/plugins/what_is_a_plugin.png[align="center"] - +image::../../../../_/images/img/plugins/what_is_a_plugin.png[Aragon OSx Plugins] How this works: - Although a Plugin is composed by the `Plugin` and `PluginSetup` contracts, the Aragon OSx protocol only knows of the `PluginSetup` contract. -- Since the `PluginSetup` contract is the one containing the plugin installation instructions, it is the one in charge of deploying the Plugin instance. Each plugin instance is specific to that DAO, deployed with its own unique parameters. -You can review how to build a `PluginSetup` contract xref:how-to-guides/plugin-development/index.adoc[here]. +- Since the `PluginSetup` contract is the one containing the plugin installation instructions, it is the one in charge of deploying the Plugin instance. Each plugin instance is specific to that DAO, deployed with its own unique parameters. You can review how to build a `PluginSetup` contract xref:guide-develop-plugin/index.adoc[here]. - The `PluginSetup` contract then interacts with the Aragon OSx framework's `PluginSetupProcessor` contract, which is in charge of applying the installation, update, or uninstallation of a plugin into a DAO. -- Publishing a Plugin into the Aragon OSx protocol is done through creating the first version of the plugin's `PluginRepo`. The plugin's `PluginRepo` instance stores all plugin versions. -You can read more about that xref:how-to-guides/plugin-development/publication/index.adoc[here]. +- Publishing a Plugin into the Aragon OSx protocol is done through creating the first version of the plugin's `PluginRepo`. The plugin's `PluginRepo` instance stores all plugin versions. You can read more about that xref:guide-develop-plugin/publishing-plugin.adoc[here]. - Except for the gas costs required, plugins are completely free to install, unless decided otherwise by the developer. -### How are Plugins installed in DAOs? +#### How are Plugins installed in DAOs? The `PluginSetup` processing is **security critical** because the permissions it handles are granted to third-party contracts. -**Safety is our top priority in the design of the whole protocol.** We want to make sure that the DAO members know exactly what -permissions are granted to whom before any processing takes place. +**Safety is our top priority in the design of the whole protocol.** We want to make sure that the DAO members know exactly what permissions are granted to whom before any processing takes place. This is why we see the installation process in two phases: -1. **Preparation:** Defining the parameters to be set on the new plugin instance and helpers, as well as requesting the permissions needed for it to work properly. -The `PluginSetup` contains the setup script where developers can perform any unprivileged operations. These will need a privileged -confirmation in the next step. -2. **Application:** The granting or revoking of the plugin's requested permissions (based on the preparation step above). -This is a privileged action performed by Aragon's `PluginSetupProcessor` (you can understand it as the "installer"), -so that the plugin becomes effectively installed or uninstalled. It gets executed whenever someone with `ROOT` privileges on -the DAO applies it (most likely through a proposal). +1. **Preparation:** Defining the parameters to be set on the new plugin instance and helpers, as well as requesting the permissions needed for it to work properly. The `PluginSetup` contains the setup script where developers can perform any unprivileged operations. These will need a privileged confirmation in the next step. +2. **Application:** The granting or revoking of the plugin's requested permissions (based on the preparation step above). This is a privileged action performed by Aragon's `PluginSetupProcessor` (you can understand it as the "installer"), so that the plugin becomes effectively installed or uninstalled. It gets executed whenever someone with `ROOT` privileges on the DAO applies it (most likely through a proposal). -The `PluginSetupProcessor` is the Aragon contract in charge of invoking the `prepareInstallation()` function from your plugin's `PluginSetup` -contract and use it to prepare the installation and (eventually) apply it once it has been approved by the DAO. +The `PluginSetupProcessor` is the Aragon contract in charge of invoking the `prepareInstallation()` function from your plugin's `PluginSetup` contract and use it to prepare the installation and (eventually) apply it once it has been approved by the DAO. -#### What happens during the Plugin Preparation? +##### What happens during the Plugin Preparation? The preparation of a `PluginSetup` contract proceeds as follows: @@ -49,16 +40,15 @@ The preparation of a `PluginSetup` contract proceeds as follows: 2. The DAO builder defines the parameters and settings that he/she wants for their DAO. Depending on the case, the `prepareInstallation`, `prepareUpdate`, or `prepareUninstallation` method in the `PluginSetup` contract is called through the `PluginSetupProcessor` (and creates a unique setup ID). -3. The link:https://github.com/aragon/osx/blob/e24d9fa3bd6d5a4c9f5936c14ccda1fe9886c2b0/packages/contracts/src/framework/plugin/setup/PluginSetup.sol[[`PluginSetup`]] contract deploys all the contracts -and gathers addresses and other input arguments required for the installation/uninstallation/upgrade instructions. This can include: +3. The link:https://github.com/aragon/osx/blob/e24d9fa3bd6d5a4c9f5936c14ccda1fe9886c2b0/packages/contracts/src/framework/plugin/setup/PluginSetup.sol[`PluginSetup`] contract deploys all the contracts and gathers addresses and other input arguments required for the installation/uninstallation/upgrade instructions. This can include: - - deployment of new contracts - - initialization of new storage variables - - deprecating/decommissioning outdated (helper) contracts - - governance settings or other attributes - - ... + * deployment of new contracts + * initialization of new storage variables + * deprecating/decommissioning outdated (helper) contracts + * governance settings or other attributes + * ... -Because the addresses of all associated contracts are now known, a static permission list can be emitted, hashed, and stored on-chain. + Because the addresses of all associated contracts are now known, a static permission list can be emitted, hashed, and stored on-chain. 4. Once the Plugin installation has been prepared, we use it as the parameter of the `applyInstallation()` action. Once encoded, this action is what must be added to the `Action[]` array of the installation proposal. That way, when the proposal passes, the action becomes executable and the plugin can be installed in the DAO using the parameters defined in the prepare installation process. For a plugin to be installed, it needs to be approved by the governance mechanism (plugin) of the organization, passed as the encoded action of a proposal, and executed by a signer. @@ -66,11 +56,14 @@ TIP: The governance plugin can be a simple majority vote, an optimistic process This gives the DAO members the opportunity to check which permissions the `PluginSetup` contract request before granting/revoking them. -Plugin setup proposals must be carefully examined as they can be a potential security risk if the `PluginSetup` contract comes from -an untrusted source. To learn more visit the xref:how-it-works/framework/plugin-management/plugin-setup/security-risk-mitigation.adoc[Security] section. +Plugin setup proposals must be carefully examined as they can be a potential security risk if the `PluginSetup` contract comes from an untrusted source. +To learn more visit the xref:guide-set-up-dao/keep-dao-safe.adoc#risks_and_their_mitigation[Security] section. +// -#### What happens during the Preparation Application? +##### What happens during the Preparation Application? After this initial preparation transaction, the addresses and permissions related to the plugin become apparent. The members of a governance plugin with permissions can decide if the installation proposal should be accepted or denied. @@ -84,15 +77,15 @@ This is processed as follows: 3. If the hash is valid, the list is processed and `PluginSetupProcessor` conducts the requested sequence of `grant`, `grantWithCondition` and `revoke` calls on the owning DAO. Finally, the `PluginSetupProcessor` asks the DAO to revoke the `ROOT_PERMISSION_ID` permission from itself. -TIP: The two-step setup procedure in Aragon OSx is not limited to the setup of only one plugin — you can **setup multiple plugins at once** -by first preparing them in a single proposal and then processing the entire setup sequence in one transaction. This is powerful and -allows you to **transform your entire DAO in one proposal**, for example, to install a new governance plugin (e.g., a gasless ZK-vote) and finance plugin (e.g., to stream loans to your members), while uninstalling your old ERC20 token vote in one go. +TIP: The two-step setup procedure in Aragon OSx is not limited to the setup of only one plugin — you can **setup multiple plugins at once** by first preparing them in a single proposal and then processing the entire setup sequence in one transaction. This is powerful and allows you to **transform your entire DAO in one proposal**, for example, to install a new governance plugin (e.g., a gasless ZK-vote) and finance plugin (e.g., to stream loans to your members), while uninstalling your old ERC20 token vote in one go. In the next sections, you will learn about how plugins are curated on Aragon's repository. +.a +image::../../../../_/images/optimized-svg/plugins/plugin-installation.drawio.svg[Schematic depiction of the plugin installation process.] +.b +image::../../../../_/images/optimized-svg/plugins/plugin-update.drawio.svg[Schematic depiction of the plugin update process.] +.c +image::../../../../_/images/optimized-svg/plugins/plugin-uninstallation.drawio.svg[Schematic depiction of the plugin uninstallation process.] -image::../../../../../_/images/optimized-svg/plugins/plugin-installation.drawio.svg[align="center"] -image::../../../../../_/images/optimized-svg/plugins/plugin-update.drawio.svg[align="center"] -image::../../../../../_/images/optimized-svg/plugins/plugin-uninstallation.drawio.svg[align="center"] - - +Simplified overview of the two-transaction plugin *a.* installation, *b.* update, and *c.* uninstallation process with the involved contracts as rounded rectangles, interactions between them as arrows, and relations as dashed lines. The first and second transaction are distinguished by numbering as well as solid and dotted lines, respectively. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.adoc b/packages/contracts/docs/modules/ROOT/pages/framework/repo-factory-registry.adoc similarity index 70% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.adoc rename to packages/contracts/docs/modules/ROOT/pages/framework/repo-factory-registry.adoc index 351e85347..e71418a5a 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/framework/repo-factory-registry.adoc @@ -4,8 +4,9 @@ To be available for installation in the Aragon OSx framework, a `PluginRepo` must be created for each plugin. The `PluginRepo` creation process is handled by: -- The TODO:GIORGI [`PluginRepoFactory`](../../../../03-reference-guide/framework/plugin/repo/PluginRepoFactory.md): who creates the `PluginRepo` instance for each plugin to hold all plugin versions -- The TODO:GIORGI [`PluginRepoRegistry`](../../../../03-reference-guide/framework/plugin/repo/PluginRepoRegistry.md): who registers the Plugin into the Protocol for DAOs to install. +- The xref:api:framework.adoc#PluginRepoFactory[PluginRepoFactory]: who creates the `PluginRepo` instance for each plugin to hold all plugin versions. +- The xref:api:framework.adoc#PluginRepoRegistry[PluginRepoRegistry]: who registers the Plugin into the Protocol for DAOs to install. + ### The `PluginRepoFactory` Contract @@ -30,14 +31,14 @@ function createPluginRepoWithFirstVersion( ) external returns (PluginRepo pluginRepo); ``` -It also registers the plugin in the Aragon OSx `PluginRepoRegistry`contract with an xref:how-it-works/framework/ens-names.adoc[ENS subdomain] under the `plugin.dao.eth` domain managed by Aragon. +It also registers the plugin in the Aragon OSx `PluginRepoRegistry` contract with an xref:framework/ens-registrar.adoc[ENS subdomain] under the `plugin.dao.eth` domain managed by Aragon. -Additional to the information required by the xref:how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.adoc#the-pluginrepo-contract[`createVersion` function discussed earlier], it receives: +Additional to the information required by the xref:framework/plugin-repos.adoc#the_pluginrepo_contract[`createVersion` function discussed earlier], it receives: - A valid ENS `_subdomain` unique name composed of letters from a-z, all in lower caps, separated by a `-`. For ex: `token-voting-plugin`. - The address of the plugin repo maintainer who ends up having the `ROOT_PERMISSION_ID`, `MAINTAINER_PERMISSION_ID`, and `UPGRADE_REPO_PERMISSION_ID` permissions. These permissions enable the maintainer to call the internal `PermissionManager`, the `createVersion` and `updateReleaseMetadata` functions as well as upgrading the plugin contract. -For more details visit the TODO:GIORGI [`PluginRepoFactory` Reference Guide entry](../../../../03-reference-guide/framework/plugin/repo/PluginRepoFactory.md). +For more details visit the xref:api:framework.adoc#PluginRepoFactory[`PluginRepoFactory` Reference Guide entry]. ### The `PluginRepoRegistry` Contract @@ -55,4 +56,4 @@ address pluginRepo } ``` -For more details visit the TODO:GIORGI [`PluginRepoRegistry` reference guide entry](../../../../03-reference-guide/framework/plugin/repo/PluginRepoRegistry.md). +For more details visit the xref:api:framework.adoc#PluginRepoRegistry[`PluginRepoRegistry` reference guide entry]. diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/design-your-plugin.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/design-your-plugin.adoc new file mode 100644 index 000000000..e4cd1e033 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/design-your-plugin.adoc @@ -0,0 +1,304 @@ += Designing your plugin + +== Governance Plugins + +### How to Build a Governance Plugin + +One of the most common use cases for plugins are governance plugins. Governance plugins are plugins DAOs install to help them make decisions. + +#### What are Governance Plugins + +Governance plugins are characterized by the **ability to execute actions in the DAO** they have been installed to. Accordingly, the `EXECUTE_PERMISSION_ID` is granted on installation on the installing DAO to the governance plugin contract. + +```solidity +grant({ + where: installingDao, + who: governancePlugin, + permissionId: EXECUTE_PERMISSION_ID +}); +``` + +Beyond this fundamental ability, governance plugins usually implement two interfaces: + +- xref:guide-develop-plugin/design-your-plugin#proposals[The `IProposal` interface] introducing the **notion of proposals** and how they are created and executed. +- xref:guide-develop-plugin/design-your-plugin#membership[The `IMembership` interface] introducing the **notion of membership** to the DAO. + +#### Examples of Governance Plugins + +Some examples of governance plugins are: + +- link:https://github.com/aragon/osx/tree/main/packages/contracts/src/plugins/governance/majority-voting/token[A token-voting plugin]: Results are based on what the majority votes and the vote's weight is determined by how many tokens an account holds. Ex: Alice has 10 tokens, Bob 2, and Alice votes yes, the yes wins. +- link:https://github.com/aragon/osx/tree/main/packages/contracts/src/plugins/governance/multisig[Multisig plugin]: A determined set of addresses is able to approve. Once `x` amount of addresses approve (as determined by the plugin settings), then the proposal automatically succeeds. +- link:https://github.com/aragon/osx/tree/main/packages/contracts/src/plugins/governance/admin[Admin plugin]: One address can create and immediately execute proposals on the DAO (full control). +- link:https://github.com/aragon/osx/tree/main/packages/contracts/src/plugins/governance/majority-voting/addresslist[Addresslist plugin]: Majority-based voting, where list of addresses are able to vote in decision-making for the organization. Unlike a multisig, everybody here is expected to vote yes/no/abstain within a certain time frame. + +// + +// + + + +### Proposals + +#### The `IProposal` Interface + +The `IProposal` interface is used to create and execute proposals containing actions and a description. + +The interface is defined as follows: + +```solidity +interface IProposal { + /// @notice Emitted when a proposal is created. + /// @param proposalId The ID of the proposal. + /// @param creator The creator of the proposal. + /// @param startDate The start date of the proposal in seconds. + /// @param endDate The end date of the proposal in seconds. + /// @param metadata The metadata of the proposal. + /// @param actions The actions that will be executed if the proposal passes. + /// @param allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. + event ProposalCreated( + uint256 indexed proposalId, + address indexed creator, + uint64 startDate, + uint64 endDate, + bytes metadata, + IDAO.Action[] actions, + uint256 allowFailureMap + ); + + /// @notice Emitted when a proposal is executed. + /// @param proposalId The ID of the proposal. + event ProposalExecuted(uint256 indexed proposalId); + + /// @notice Returns the proposal count determining the next proposal ID. + /// @return The proposal count. + function proposalCount() external view returns (uint256); +} +``` + +This interface contains two events and one function + +##### `ProposalCreated` event + +This event should be emitted when a proposal is created. It contains the following parameters: + +- `proposalId`: The ID of the proposal. +- `creator`: The creator of the proposal. +- `startDate`: The start block number of the proposal. +- `endDate`: The end block number of the proposal. +- `metadata`: This should contain a metadata ipfs hash or any other type of link to the metadata of the proposal. +- `actions`: The actions that will be executed if the proposal passes. +- `allowFailureMap`: A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. + +##### `ProposalExecuted` event + +This event should be emitted when a proposal is executed. It contains the proposal ID as a parameter. + +##### `proposalCount` function + +This function should return the proposal count determining the next proposal ID. + +#### Usage + +```solidity +contract MyPlugin is IProposal { + uint256 public proposalCount; + + function createProposal( + uint64 _startDate, + uint64 _endDate, + bytes calldata _metadata, + IDAO.Action[] calldata _actions, + uint256 _allowFailureMap + ) external { + proposalCount++; + emit ProposalCreated( + proposalCount, + msg.sender, + _startDate, + _endDate, + _metadata, + _actions, + _allowFailureMap + ); + } + + function proposalCount() external view returns (uint256) { + return proposalCount; + } + + function executeProposal(uint256 _proposalId) external { + // Execute the proposal + emit ProposalExecuted(_proposalId); + } +} +``` + +### Membership + +#### The `IMembership` Interface + +The `IMembership` interface defines common functions and events for for plugins that keep track of membership in a DAO. This plugins can be used to define who can vote on proposals, who can create proposals, etc. The list of members can be defined in the plugin itself or by a contract that defines the membership like an ERC20 or ERC721 token. + +The interface is defined as follows: + +```solidity title= +/// @notice An interface to be implemented by DAO plugins that define membership. +interface IMembership { + /// @notice Emitted when members are added to the DAO plugin. + /// @param members The list of new members being added. + event MembersAdded(address[] members); + + /// @notice Emitted when members are removed from the DAO plugin. + /// @param members The list of existing members being removed. + event MembersRemoved(address[] members); + + /// @notice Emitted to announce the membership being defined by a contract. + /// @param definingContract The contract defining the membership. + event MembershipContractAnnounced(address indexed definingContract); + + /// @notice Checks if an account is a member of the DAO. + /// @param _account The address of the account to be checked. + /// @return Whether the account is a member or not. + /// @dev This function must be implemented in the plugin contract that introduces the members to the DAO. + function isMember(address _account) external view returns (bool); +} +``` + +The interface contains three events and one function. + +##### `MembersAdded` event + +The members added event should be emitted when members are added to the DAO plugin. It only contains one `address[] members` parameter that references the list of new members being added. + +- `members`: The list of new members being added. + +##### `MembersRemoved` event + +The members added event should be emitted when members are removed from the DAO plugin. It only contains one `address[] members` parameter that references the list of members being removed. + +##### `MembershipContractAnnounced` event + +This event should be emitted during the initialization of the membership plugin to announce the membership being defined by a contract. It contains the defining contract as a parameter. + +##### `isMember` function + +This is a simple function that should be implemented in the plugin contract that introduces the members to the DAO. It checks if an account is a member of the DAO and returns a boolean value. + +#### Usage + +```solidity + +contract MyPlugin is IMembership { + address public membershipContract; + + constructor(address tokenAddress) { + // Initialize the membership contract + // ... + membershipContract = tokenAddress; + emit MembershipContractAnnounced(tokenAddress); + } + + function isMember(address _account) external view returns (bool) { + // Check if the account is a member of the DAO + // ... + } + + // Other plugin functions + function addMembers(address[] memory _members) external { + // Add members to the DAO + // ... + emit MembersAdded(_members); + } + + function removeMembers(address[] memory _members) external { + // Remove members from the DAO + // ... + emit MembersRemoved(_members); + } +} + +``` + +== Choosing the Plugin Upgradeability + +### How to Choose the Base Contract for Your Plugin + +Although it is not mandatory to choose one of our interfaces as the base contracts for your plugins, we do offer some options for you to inherit from and speed up development. + +The needs of your plugin determine the type of plugin you may want to choose. This is based on: + +- the need for a plugin's upgradeability +- whether you need it deployed by a specific deployment method +- whether you need it to be compatible with meta transactions + +In this regard, we provide 3 options for base contracts you can choose from: + +- `Plugin` for instantiation via `new` +- `PluginClones` for [minimal proxy pattern link:https://eips.ethereum.org/EIPS/eip-1167[ERC-1167]] deployment +- `PluginUUPSUpgradeable` for [UUPS pattern link:https://eips.ethereum.org/EIPS/eip-1822[ERC-1822]] deployment + +Let's take a look at what this means for you. + +### Upgradeability & Deployment + +Upgradeability and the deployment method of a plugin contract go hand in hand. The motivation behind upgrading smart contracts is nicely summarized by OpenZeppelin: + +> Smart contracts in Ethereum are immutable by default. Once you create them there is no way to alter them, effectively acting as an unbreakable contract among participants. +> +> However, for some scenarios, it is desirable to be able to modify them [...] +> +> - to fix a bug [...], +> - to add additional features, or simply to +> - change the rules enforced by it. +> +> Here’s what you’d need to do to fix a bug in a contract you cannot upgrade: +> +> 1. Deploy a new version of the contract +> 2. Manually migrate all state from the old one contract to the new one (which can be very expensive in terms of gas fees!) +> 3. Update all contracts that interacted with the old contract to use the address of the new one +> 4. Reach out to all your users and convince them to start using the new deployment (and handle both contracts being used simultaneously, as users are slow to migrate +> +> _source: link:https://docs.openzeppelin.com/learn/upgrading-smart-contracts#whats-in-an-upgrade[OpenZeppelin: What's in an upgrade]_ + +Some key things to keep in mind: + +- With upgradeable smart contracts, you can modify their code while keep using or even extending the storage (see the guide link:https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable[Writing Upgradeable Contracts] by OpenZeppelin). +- To enable upgradeable smart contracts (as well as cheap contract clones), the proxy pattern is used. +- Depending on your upgradeability requirements and the deployment method you choose, you can also greatly reduce the gas costs to distribute your plugin. However, the upgradeability and deployment method can introduce caveats during xref:framework/plugin-setup-processor.adoc[the plugin setup], especially when updating from an older version to a new one. + +// TODO:CLAUDIA add table cells style +|=== +| |`new` Instantiation | Minimal Proxy (Clones)| Transparent Proxy| UUPS Proxy + +| upgradeability +|no +| no +| yes +| yes +| gas costs +| high +| very low +| moderate +| low +| difficulty +| low +| low +| high +| high +|=== + +Accordingly, we recommend to use link:https://eips.ethereum.org/EIPS/eip-1167[minimal proxies (ERC-1167)] for non-upgradeable and link:https://eips.ethereum.org/EIPS/eip-1822[UUPS proxies (ERC-1822)] for upgradeable plugins. +To help you with developing and deploying your plugin within the Aragon infrastructure, we provide the following implementation that you can inherit from: + +- `Plugin` for instantiation via `new` +- `PluginClones` for [minimal proxy pattern link:https://eips.ethereum.org/EIPS/eip-1167[ERC-1167]] deployment +- `PluginUUPSUpgradeable` for [UUPS pattern link:https://eips.ethereum.org/EIPS/eip-1822[ERC-1822]] deployment + +#### Caveats of Non-upgradeable Plugins + +Aragon plugins using the non-upgradeable smart contracts bases (`Plugin`, `PluginCloneable`) can be cheap to deploy (i.e., using clones) but **cannot be updated**. + +Updating, in distinction from upgrading, will call Aragon OSx' internal process for switching from an older plugin version to a newer one. + +WARNING: To switch from an older version of a non-upgradeable contract to a newer one, the underlying contract has to be replaced. In consequence, the state of the older version is not available in the new version anymore, unless it is migrated or has been made publicly accessible in the old version through getter functions. \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/follow-best-practices.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/follow-best-practices.adoc new file mode 100644 index 000000000..50e22f821 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/follow-best-practices.adoc @@ -0,0 +1,25 @@ += Before Starting + +== Advice for Developing a Plugin + +### DOs 👌 + +- Document your contracts using link:https://docs.soliditylang.org/en/v0.8.17/natspec-format.html[NatSpec]. +- Test your contracts, e.g., using toolkits such as link:https://hardhat.org/hardhat-runner/docs/guides/test-contracts[hardhat (JS)] or link:https://book.getfoundry.sh/forge/tests[Foundry (Rust)]. +- Use the `auth` modifier to control the access to functions in your plugin instead of `onlyOwner` or similar. +- Write plugins implementations that need minimal permissions on the DAO. +- Write `PluginSetup` contracts that remove all permissions on uninstallation that they requested during installation or updates. +- Plan the lifecycle of your plugin (need for upgrades). +- Follow our xref:guide-develop-plugin/publishing-plugin.adoc#how_to_add_a_new_version_of_your_plugin[versioning guidelines]. + +### DON'Ts ✋ + +- Leave any contract uninitialized. +- Grant the `ROOT_PERMISSION_ID` permission to anything or anyone. +- Grant with `who: ANY_ADDR` unless you know what you are doing. +- Expect people to grant or revoke any permissions manually during the lifecycle of a plugin. The `PluginSetup` should take this complexity away from the user and after uninstallation, all permissions should be removed. +- Write upgradeable contracts that: + - Repurpose existing storage (in upgradeable plugins). + - Inherit from previous versions as this can mess up the inheritance chain. Instead, write self-contained contracts. + +In the following sections, you will learn about the details about plugin development. diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/index.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/index.adoc new file mode 100644 index 000000000..640013fd8 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/index.adoc @@ -0,0 +1,70 @@ += How to build a DAO Plugin + +== Plugin Development Quickstart Guide + +Plugins are how we extend the functionality for DAOs. In Aragon OSx, everything a DAO can do is based on Plugin functionality enabled through permissions. + +In this Quickstart guide, we will use the Aragon Hardhat template to set up a plugin. + +## Setting up your environment + +We recommend using our link:https://github.com/aragon/osx-plugin-template-hardhat[hardhat template] to get started. If you don't have +it installed, you can do so by running: + +```bash +git clone github.com/aragon/osx-plugin-template-hardhat +``` + +Once you have cloned the repository the first step is to add a `.env` file with your `ALCHEMY_API_KEY`, +there is a link:https://github.com/aragon/osx-plugin-template-hardhat/blob/main/.env.example[.env.example] file you can use as a template. + +This file contains more env variables that you may need throughout the development process, but to get started you only need to +add the `ALCHEMY_API_KEY`. + +```bash +# INCOMPLETE - PLEASE FILL IN THE MISSING VALUES +# GENERAL + +## The network used for testing purposes +NETWORK_NAME="sepolia" # ["mainnet", "sepolia", "polygon", "baseMainnet", "arbitrum"] + +# CONTRACTS + +## One or multiple hex encoded private keys separated by commas `,` replacing the hardhat default accounts. +PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" # Default hardhat account 0 private key. DON'T USE FOR DEPLOYMENTS + +## Alchemy RPC endpoint credentials +ALCHEMY_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" +``` + +Once the `.env` file is created, you can run the following command to install the dependencies: + +```bash +yarn install && cd packages/contracts && yarn install && yarn build && yarn typechain +``` + +Now you are ready to start developing your plugin. You should have two files called `MyPlugin.sol` and `MyPluginSetup.sol` inside +the `contracts` folder. + +The template is already set up with a basic plugin and plugin setup contract. You can start by modifying these files to create +your own plugin. The tests and deployment scripts are also set up for you to use. + +## Next Steps + +For more information on how to use the template, you can check the link:https://github.com/aragon/osx-plugin-template-hardhat/blob/main/README.md[README] and +the link:https://github.com/aragon/osx-plugin-template-hardhat/blob/main/USAGE_GUIDE.md[USAGE GUIDE]. + +For more information on how to develop a plugin, you can check our plugin development guides: + +- xref:guide-develop-plugin/design-your-plugin.adoc[Design your plugin, different plugin types] +- xref:guide-develop-plugin/write-plugin-contract.adoc[Writing your plugin contract] +- xref:guide-develop-plugin/write-plugin-setup-contract.adoc[Writing your plugin setup contract] +- xref:guide-develop-plugin/write-upgradeable-plugin.adoc[Writing upgradeable plugin] +- xref:guide-develop-plugin/upgrade-plugin.adoc[Upgrading your plugin] +- xref:guide-develop-plugin/follow-best-practices.adoc[Best practices and patterns] +- xref:guide-develop-plugin/publishing-plugin.adoc[Publishing your plugin] + + + +IMPORTANT: This plugin template uses version TODO:GIORGI `1.4.0-alpha.5` of the Aragon OSx protocol. This version is still in development and +is not audited yet. diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/publishing-plugin.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/publishing-plugin.adoc new file mode 100644 index 000000000..9c3fb815b --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/publishing-plugin.adoc @@ -0,0 +1,240 @@ += Publication of your Plugin into Aragon OSx + +== How to publish a plugin into Aragon's plugin registry + +Once you've deployed your Plugin Setup contract, you will be able to publish your plugin into Aragon's plugin registry so any +Aragon DAO can install it. + +### 1. Make sure your plugin is deployed in the right network + +Make sure your Plugin Setup contract is deployed in your network of choice (you can find all of the networks we support link:https://github.com/aragon/osx-commons/tree/develop/configs/src/deployments/json[here]). +You will need the address of your Plugin Setup contract to be able to publish the plugin into the protocol. + +### 2. Publishing your plugin + +Every plugin in Aragon can have future versions, so when publishing a plugin to the Aragon protocol, we're really creating a link:https://github.com/aragon/osx/blob/develop/packages/contracts/src/framework/plugin/repo/PluginRepo.sol[PluginRepo] instance for each plugin, +which will contain all of the plugin's versions. + +To publish a plugin, we will use Aragon's `PluginRepoFactory` contract - in charge of creating `PluginRepo` instances containing your plugin's versions. +To do this, we will call its `createPluginRepoWithFirstVersion` function, which will link:https://github.com/aragon/core/blob/develop/packages/contracts/src/framework/plugin/repo/PluginRepoFactory.sol#L48[create the first version of a plugin] +and add that new `PluginRepo` address into the `PluginRepoRegistry` containing all available plugins within the protocol. + +You can find all of the addresses of `PluginRepoFactory` contracts by network link:https://github.com/aragon/osx-commons/tree/develop/configs/src/deployments/json[here]. + +To create more versions of your plugin in the future, you'll call on the link:https://github.com/aragon/osx/blob/develop/packages/contracts/src/framework/plugin/repo/PluginRepo.sol#L128[createVersion function] +from the `PluginRepo` instance of your plugin. When you publish your plugin, you'll be able to find the address of your plugin's `PluginRepo` instance within the transaction data. + +### 3. Publishing subsequent builds + +When publishing subsequent builds, you want to use the `createVersion` function in the `PluginRepo` contract (link:https://github.com/aragon/osx/blob/develop/packages/contracts/src/framework/plugin/repo/PluginRepo.sol#L132[check out the function's source code here]). + +To deploy your plugin, follow the steps in the link:https://github.com/aragon/osx-plugin-template-hardhat/blob/main/README.md#deployment[osx-plugin-template-hardhat README.md]. + + + +== How to add a new version of your plugin + +The Aragon OSx protocol has an on-chain versioning system built-in, which distinguishes between releases and builds. + +- **Releases** contain breaking changes, which are incompatible with preexisting installations. Updates to a different release are +not possible. Instead, you must install the new plugin release and uninstall the old one. +- **Builds** are minor/patch versions within a release, and they are meant for compatible upgrades only +(adding a feature or fixing a bug without changing anything else). + +Builds are particularly important for `UUPSUpgradeable` plugins, whereas a non-upgradeable plugin will work off of only releases. + +Given a version tag `RELEASE.BUILD`, we can infer that: + +1. We are doing a `RELEASE` version when we apply breaking changes affecting the interaction with other contracts on the blockchain to: + +* The `Plugin` implementation contract such as the +** change or removal of storage variables +** removal of external functions +** change of external function headers + +2. We are doing a `BUILD` version when we apply backward compatible changes not affecting the interaction with other contracts on the blockchain to: + +* The `Plugin` implementation contract such as the + ** addition of + *** storage variables + *** external functions + + ** change of + *** external function bodies + + ** addition, change, or removal of + *** internal functions + *** constants + *** immutables + *** events + *** errors + +* The `PluginSetup` contract such as + ** addition, change, or removal of + *** input parameters + *** helper contracts + *** requested permissions + +* The release and build `metadata` URIs such as the + ** change of + *** the plugin setup ABI + *** the plugin UI components + *** the plugin description + +== Plugin Metadata Specification + +The plugin metadata is necessary to allow the App frontend to interact with any plugins: + +* Now: generic setup (installation, update, uninstallation) + ** Allows the frontend to render the necessary fields for the input being required to setup the plugin (e.g., the list of initial members of the Multisig plugin) +* Future: render a UI in a generic way (buttons, text fields, flows) within the specs of the Open Design System (ODS) (e.g. manage the list of Multisig members or the approval settings) + +Currently, two kinds of metadata exist: + +1. Release metadata +2. Build metadata + +### Release Metadata + +The release metadata is a `.json` file stored on IPFS with its IPFS CID published for each release in the xref:framework/plugin-repos.adoc[PluginRepo](see also the section about xref:#how_to_add_a_new_version_of_your_plugin[versioning]). + +The intention is to provide an appealing overview of each releases functionality. +It can be updated with each call to xref:api:framework.adoc#PluginRepo-createVersion-uint8-address-bytes-bytes-[`createVersion()`] in `IPluginRepo` by the repo maintainer. + +It can be replaced at any time with xref:api:framework.adoc#PluginRepo-updateReleaseMetadata-uint8-bytes-[`updateReleaseMetadata()`] in `IPluginRepo` by the repo maintainer. + +The `release-metadata.json` file consists of the following entries: + +|=== +|Key |Type |Description + +| name +| `string` +| Name of the plugin (e.g. `"Multisig"`) + +| description +| `string` +| Description of the plugin release and its functionality. + +| images +| UNSPECIFIED +| Optional. Contains a series of images advertising the plugins functionality.. + +|=== + + +#### Example + +```json +{ + "name": "Multisig", + "description": "", + "images": {} +} +``` + +### Build Metadata + +The build metadata is a `.json` file stored on IPFS with its IPFS CID published for each build **only once** +in the xref:framework/plugin-repos.adoc[PluginRepo] (see also the section about xref:#how_to_add_a_new_version_of_your_plugin[versioning]). + +The intention is to inform about the changes that were introduced in this build compared to the previous one and give instructions to the App frontend and other users on how to interact with the plugin setup and implementation contract. +It can be published **only once** with the call to xref:api:framework.adoc#PluginRepo-createVersion-uint8-address-bytes-bytes-[`createVersion()`] in `IPluginRepo` by the repo maintainer. + + +|=== +|Key |Type |Description + +| ui +| UNSPECIFIED +| A special formatted object containing instructions for the App frontend on how to render the plugin's UI. + +| change +| `string` +| Description of the code and UI changes compared to the previous build of the same release. + +| pluginSetup +| `object` +| Optional. Contains a series of images advertising the plugins functionality. + +|=== + +Each build metadata contains the following fields: + +- one `"prepareInstallation"` object +- one `"prepareUninstallation"` object +- 0 to N `"prepareUpdate"` objects enumerated from 1 to N+1 + +Each `"prepare..."` object contains: + +|=== +|Key |Type |Description + +| description +| `string` +| The description of what this particular setup step is doing and what it requires the input for. + +| inputs +| `object[]` +| A description of the inputs required for this setup step following the link:https://docs.ethers.org/v5/api/utils/abi/formats/#abi-formats--solidity[Solidity JSON ABI] format enriched with an additional `"description"` field for each element. + +|=== + + + +By following the Solidity JSON ABI format for the inputs, we followed an established standard, have support for complex types (tuples, arrays, nested versions of the prior) and allow for future extensibility (such as the human readable description texts that we have added). + +#### Example + +```json +{ + "ui": {}, + "change": "- The ability to create a proposal now depends on the membership status of the current instead of the snapshot block.\n- Added a check ensuring that the initial member list cannot overflow.", + "pluginSetup": { + "prepareInstallation": { + "description": "The information required for the installation.", + "inputs": [ + { + "internalType": "address[]", + "name": "members", + "type": "address[]", + "description": "The addresses of the initial members to be added." + }, + { + "components": [ + { + "internalType": "bool", + "name": "onlyListed", + "type": "bool", + "description": "Whether only listed addresses can create a proposal or not." + }, + { + "internalType": "uint16", + "name": "minApprovals", + "type": "uint16", + "description": "The minimal number of approvals required for a proposal to pass." + } + ], + "internalType": "struct Multisig.MultisigSettings", + "name": "multisigSettings", + "type": "tuple", + "description": "The initial multisig settings." + } + ], + "prepareUpdate": { + "1": { + "description": "No input is required for the update.", + "inputs": [] + } + }, + "prepareUninstallation": { + "description": "No input is required for the uninstallation.", + "inputs": [] + } + } + } +} +``` + + +// TODO merge this sections and clean up redundancy, consider also framework and core sections. \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/upgrade-plugin.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/upgrade-plugin.adoc new file mode 100644 index 000000000..055814855 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/upgrade-plugin.adoc @@ -0,0 +1,536 @@ += Subsequent Builds + + +== How to upgrade an Upgradeable Plugin + +Updating an Upgradeable plugin means we want to direct the implementation of our functionality to a new build, rather than +the existing one. + +In this tutorial, we will go through how to update the version of an Upgradeable plugin and each component needed. + +### 1. Create the new build implementation contract + +Firstly, you want to create the new build implementation contract the plugin should use. You can read more about how to do +this in the xref:guide-develop-plugin/upgrade-plugin.adoc[How to create a subsequent build implementation to an Upgradeable Plugin] guide. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.21; + +import {IDAO, PluginUUPSUpgradeable} from '@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol'; + +/// @title SimpleStorage build 2 +contract SimpleStorageBuild2 is PluginUUPSUpgradeable { + bytes32 public constant STORE_PERMISSION_ID = keccak256('STORE_PERMISSION'); + + uint256 public number; // added in build 1 + address public account; // added in build 2 + + /// @notice Initializes the plugin when build 2 is installed. + function initializeBuild2( + IDAO _dao, + uint256 _number, + address _account + ) external reinitializer(2) { + __PluginUUPSUpgradeable_init(_dao); + number = _number; + account = _account; + } + + /// @notice Initializes the plugin when the update from build 1 to build 2 is applied. + /// @dev The initialization of `SimpleStorageBuild1` has already happened. + function initializeFromBuild1(address _account) external reinitializer(2) { + account = _account; + } + + function storeNumber(uint256 _number) external auth(STORE_PERMISSION_ID) { + number = _number; + } + + function storeAccount(address _account) external auth(STORE_PERMISSION_ID) { + account = _account; + } +} +``` + +### 2. Write a new Plugin Setup contract + +In order to do update a plugin, we need a `prepareUpdate()` function in our Plugin Setup contract which points the functionality to a +new build, as we described in the xref:guide-develop-plugin/upgrade-plugin.adoc[How to create a subsequent build implementation to an Upgradeable Plugin] guide. +The `prepareUpdate()` function must transition the plugin from the old build state into the new one so that it ends up having the +same permissions (and helpers) as if it had been freshly installed. + +In contrast to the original build 1, build 2 requires two input arguments: `uint256 _number` and `address _account` that we decode +from the bytes-encoded input `_data`. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.21; + +import {PermissionLib} from '@aragon/osx/core/permission/PermissionLib.sol'; +import {PluginSetup, IPluginSetup} from '@aragon/osx/framework/plugin/setup/PluginSetup.sol'; +import {SimpleStorageBuild2} from './SimpleStorageBuild2.sol'; + +/// @title SimpleStorageSetup build 2 +contract SimpleStorageBuild2Setup is PluginSetup { + address private immutable simpleStorageImplementation; + + constructor() { + simpleStorageImplementation = address(new SimpleStorageBuild2()); + } + + /// @inheritdoc IPluginSetup + function prepareInstallation( + address _dao, + bytes memory _data + ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + (uint256 _number, address _account) = abi.decode(_data, (uint256, address)); + + plugin = createERC1967Proxy( + simpleStorageImplementation, + abi.encodeWithSelector(SimpleStorageBuild2.initializeBuild2.selector, _dao, _number, _account) + ); + + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[](1); + + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleStorageBuild2(this.implementation()).STORE_PERMISSION_ID() + }); + + preparedSetupData.permissions = permissions; + } + + /// @inheritdoc IPluginSetup + function prepareUpdate( + address _dao, + uint16 _currentBuild, + SetupPayload calldata _payload + ) + external + pure + override + returns (bytes memory initData, PreparedSetupData memory preparedSetupData) + { + (_dao, preparedSetupData); + + if (_currentBuild == 0) { + address _account = abi.decode(_payload.data, (address)); + initData = abi.encodeWithSelector( + SimpleStorageBuild2.initializeFromBuild1.selector, + _account + ); + } + } + + /// @inheritdoc IPluginSetup + function prepareUninstallation( + address _dao, + SetupPayload calldata _payload + ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + permissions = new PermissionLib.MultiTargetPermission[](1); + + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _payload.plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleStorageBuild2(this.implementation()).STORE_PERMISSION_ID() + }); + } + + /// @inheritdoc IPluginSetup + function implementation() external view returns (address) { + return simpleStorageImplementation; + } +} +``` + +The key thing to review in this new Plugin Setup contract is its `prepareUpdate()` function. The function only contains a +condition checking from which build number the update is transitioning to build `2`. Here, it is the build number `1` as this is the +only update path we support. Inside, we decode the `address _account` input argument provided with `bytes _data` and pass +it to the `initializeFromBuild1` function taking care of initializing the storage that was added in this build. + +### 3. Future builds + +For each build we add, we will need to add a `prepareUpdate()` function with any parameters needed to update to that implementation. + +In this third build, for example, we are modifying the bytecode of the plugin. + +**Third plugin build example, modifying the plugin's bytecode.** + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.21; + +import {IDAO, PluginUUPSUpgradeable} from '@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol'; + +/// @title SimpleStorage build 3 +contract SimpleStorageBuild3 is PluginUUPSUpgradeable { + bytes32 public constant STORE_NUMBER_PERMISSION_ID = keccak256('STORE_NUMBER_PERMISSION'); // changed in build 3 + bytes32 public constant STORE_ACCOUNT_PERMISSION_ID = keccak256('STORE_ACCOUNT_PERMISSION'); // added in build 3 + + uint256 public number; // added in build 1 + address public account; // added in build 2 + + // added in build 3 + event NumberStored(uint256 number); + event AccountStored(address account); + error AlreadyStored(); + + /// @notice Initializes the plugin when build 3 is installed. + function initializeBuild3( + IDAO _dao, + uint256 _number, + address _account + ) external reinitializer(3) { + __PluginUUPSUpgradeable_init(_dao); + number = _number; + account = _account; + + emit NumberStored({number: _number}); + emit AccountStored({account: _account}); + } + + /// @notice Initializes the plugin when the update from build 2 to build 3 is applied. + /// @dev The initialization of `SimpleStorageBuild2` has already happened. + function initializeFromBuild2() external reinitializer(3) { + emit NumberStored({number: number}); + emit AccountStored({account: account}); + } + + /// @notice Initializes the plugin when the update from build 1 to build 3 is applied. + /// @dev The initialization of `SimpleStorageBuild1` has already happened. + function initializeFromBuild1(address _account) external reinitializer(3) { + account = _account; + + emit NumberStored({number: number}); + emit AccountStored({account: _account}); + } + + function storeNumber(uint256 _number) external auth(STORE_NUMBER_PERMISSION_ID) { + if (_number == number) revert AlreadyStored(); + + number = _number; + + emit NumberStored({number: _number}); + } + + function storeAccount(address _account) external auth(STORE_ACCOUNT_PERMISSION_ID) { + if (_account == account) revert AlreadyStored(); + + account = _account; + + emit AccountStored({account: _account}); + } +} +``` + + +With each new build implementation, we will need to update the Plugin Setup contract to be able to update to that new version. +We do this through updating the `prepareUpdate()` function to support any new features that need to be set up. + +**Third plugin setup example, modifying `prepareUpdate` function**. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.21; + +import {PermissionLib} from '@aragon/osx/core/permission/PermissionLib.sol'; +import {PluginSetup, IPluginSetup} from '@aragon/osx/framework/plugin/setup/PluginSetup.sol'; +import {SimpleStorageBuild2} from '../build2/SimpleStorageBuild2.sol'; +import {SimpleStorageBuild3} from './SimpleStorageBuild3.sol'; + +/// @title SimpleStorageSetup build 3 +contract SimpleStorageBuild3Setup is PluginSetup { + address private immutable simpleStorageImplementation; + + constructor() { + simpleStorageImplementation = address(new SimpleStorageBuild3()); + } + + /// @inheritdoc IPluginSetup + function prepareInstallation( + address _dao, + bytes memory _data + ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + (uint256 _number, address _account) = abi.decode(_data, (uint256, address)); + + plugin = createERC1967Proxy( + simpleStorageImplementation, + abi.encodeWithSelector(SimpleStorageBuild3.initializeBuild3.selector, _dao, _number, _account) + ); + + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[](2); + + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleStorageBuild3(this.implementation()).STORE_NUMBER_PERMISSION_ID() + }); + + permissions[1] = permissions[0]; + permissions[1].permissionId = SimpleStorageBuild3(this.implementation()) + .STORE_ACCOUNT_PERMISSION_ID(); + + preparedSetupData.permissions = permissions; + } + + /// @inheritdoc IPluginSetup + function prepareUpdate( + address _dao, + uint16 _currentBuild, + SetupPayload calldata _payload + ) + external + view + override + returns (bytes memory initData, PreparedSetupData memory preparedSetupData) + { + if (_currentBuild == 0) { + address _account = abi.decode(_payload.data, (address)); + initData = abi.encodeWithSelector( + SimpleStorageBuild3.initializeFromBuild1.selector, + _account + ); + } else if (_currentBuild == 1) { + initData = abi.encodeWithSelector(SimpleStorageBuild3.initializeFromBuild2.selector); + } + + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[](3); + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _dao, + who: _payload.plugin, + condition: PermissionLib.NO_CONDITION, + permissionId: keccak256('STORE_PERMISSION') + }); + + permissions[1] = permissions[0]; + permissions[1].operation = PermissionLib.Operation.Grant; + permissions[1].permissionId = SimpleStorageBuild3(this.implementation()) + .STORE_NUMBER_PERMISSION_ID(); + + permissions[2] = permissions[1]; + permissions[2].permissionId = SimpleStorageBuild3(this.implementation()) + .STORE_ACCOUNT_PERMISSION_ID(); + + preparedSetupData.permissions = permissions; + } + + /// @inheritdoc IPluginSetup + function prepareUninstallation( + address _dao, + SetupPayload calldata _payload + ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + permissions = new PermissionLib.MultiTargetPermission[](2); + + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _payload.plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleStorageBuild3(this.implementation()).STORE_NUMBER_PERMISSION_ID() + }); + + permissions[1] = permissions[1]; + permissions[1].permissionId = SimpleStorageBuild3(this.implementation()) + .STORE_ACCOUNT_PERMISSION_ID(); + } + + /// @inheritdoc IPluginSetup + function implementation() external view returns (address) { + return simpleStorageImplementation; + } +} +``` + + +In this case, the `prepareUpdate()` function only contains a condition checking from which build number the update is transitioning +to build 2. Here, we can update from build 0 or build 1 and different operations must happen for each case to transition to +`SimpleAdminBuild3`. + +In the first case, `initializeFromBuild1` is called taking care of initializing `address _account` that was added in build 1 and +emitting the events added in build 2. + +In the second case, `initializeFromBuild2` is called taking care of initializing the build. Here, only the two events will be emitted. + +Lastly, the `prepareUpdate()` function takes care of modifying the permissions by revoking the `STORE_PERMISSION_ID` and granting +the more specific `STORE_NUMBER_PERMISSION_ID` and `STORE_ACCOUNT_PERMISSION_ID` permissions, that are also granted if build 2 is +freshly installed. This must happen for both update paths so this code is outside the `if` statements. + +== How to create a subsequent build to an Upgradeable Plugin + +A build is a new implementation of your Upgradeable Plugin. Upgradeable contracts offer advantages because you can cheaply change +or fix the logic of your contract without losing the storage of your contract. + +The Aragon OSx protocol has an on-chain versioning system built-in, which distinguishes between releases and builds. + +- **Releases** contain breaking changes, which are incompatible with preexisting installations. Updates to a different release are +not possible. Instead, you must install the new plugin release and uninstall the old one. +- **Builds** are minor/patch versions within a release, and they are meant for compatible upgrades +only (adding a feature or fixing a bug without changing anything else). + +In this how to guide, we'll go through how we can create these builds for our plugins. Specifically, we'll showcase two specific +types of builds - one that modifies the storage of the plugins, another one which modifies its bytecode. Both are possible and +can be implemented within the same build implementation as well. + +### 1. Make sure your previous build is deployed and published + +Make sure you have at least one build already deployed and published into the Aragon protocol. Make sure to check out our +xref:guide-develop-plugin/publishing-plugin.adoc[publishing guide] to ensure this step is done. + +### 2. Create a new build implementation + +In this second build implementation we want to update the functionality of our plugin - in this case, we want to update +the storage of our plugin with new values. Specifically, we will add a second storage variable `address public account;`. +Additional to the `initializeFromBuild2` function, we also want to add a second setter function `storeAccount` that uses +the same permission as `storeNumber`. + +As you can see, we're still inheriting from the `PluginUUPSUpgradeable` contract and simply overriding some implementation +from the previous build. The idea is that when someone upgrades the plugin and calls on these functions, they'll use this +new upgraded implementation, rather than the older one. + +```solidity +import {PluginUUPSUpgradeable, IDAO} '@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol'; + +/// @title SimpleStorage build 2 +contract SimpleStorageBuild2 is PluginUUPSUpgradeable { + bytes32 public constant STORE_PERMISSION_ID = keccak256('STORE_PERMISSION'); + + uint256 public number; // added in build 1 + address public account; // added in build 2 + + /// @notice Initializes the plugin when build 2 is installed. + function initializeBuild2( + IDAO _dao, + uint256 _number, + address _account + ) external reinitializer(2) { + __PluginUUPSUpgradeable_init(_dao); + number = _number; + account = _account; + } + + /// @notice Initializes the plugin when the update from build 1 to build 2 is applied. + /// @dev The initialization of `SimpleStorageBuild1` has already happened. + function initializeFromBuild1(address _account) external reinitializer(2) { + account = _account; + } + + function storeNumber(uint256 _number) external auth(STORE_PERMISSION_ID) { + number = _number; + } + + function storeAccount(address _account) external auth(STORE_PERMISSION_ID) { + account = _account; + } +} +``` + +Builds that you publish don't necessarily need to introduce new storage variables of your contracts and don't necessarily need to +change the storage. To read more about Upgradeability, check out link:https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable[OpenZeppelin's UUPSUpgradeability implementation here]. + +NOTE: Note that because these contracts are Upgradeable, keeping storage gaps `uint256 [50] __gap;` in dependencies is a must in +order to avoid storage corruption. To learn more about storage gaps, review OpenZeppelin's documentation link:https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps[here]. + +### 3. Alternatively, a build implementation modifying bytecode + +Updates for your contracts don't necessarily need to affect the storage, they can also modify the plugin's bytecode. +Modifying the contract's bytecode, means making changes to: + +- functions +- constants +- immutables +- events +- errors + +For this third build, then, we want to change the bytecode of our implementation as an example, so we 've introduced two +separate permissions for the `storeNumber` and `storeAccount` functions and named them `STORE_NUMBER_PERMISSION_ID` and `STORE_ACCOUNT_PERMISSION_ID` permission, respectively. +Additionally, we decided to add the `NumberStored` and `AccountStored` events as well as an error preventing users from setting the +same value twice. All these changes only affect the contract bytecode and not the storage. + +Here, it is important to remember how Solidity stores `constant`s (and `immutable`s). In contrast to normal variables, they are directly +written into the bytecode on contract creation so that we don't need to worry that the second `bytes32` constant that we added +shifts down the storage so that the value in `uint256 public number` gets lost. It is also important to note that, the `initializeFromBuild2` +could be left empty. Here, we just emit the events with the currently stored values. + +```solidity +import {PluginUUPSUpgradeable, IDAO} '@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol'; + +/// @title SimpleStorage build 3 +contract SimpleStorageBuild3 is PluginUUPSUpgradeable { + bytes32 public constant STORE_NUMBER_PERMISSION_ID = keccak256('STORE_NUMBER_PERMISSION'); // changed in build 3 + bytes32 public constant STORE_ACCOUNT_PERMISSION_ID = keccak256('STORE_ACCOUNT_PERMISSION'); // added in build 3 + + uint256 public number; // added in build 1 + address public account; // added in build 2 + + // added in build 3 + event NumberStored(uint256 number); + event AccountStored(address number); + error AlreadyStored(); + + /// @notice Initializes the plugin when build 3 is installed. + function initializeBuild3( + IDAO _dao, + uint256 _number, + address _account + ) external reinitializer(3) { + __PluginUUPSUpgradeable_init(_dao); + number = _number; + account = _account; + + emit NumberStored({number: _number}); + emit AccountStored({account: _account}); + } + + /// @notice Initializes the plugin when the update from build 2 to build 3 is applied. + /// @dev The initialization of `SimpleStorageBuild2` has already happened. + function initializeFromBuild2() external reinitializer(3) { + emit NumberStored({number: number}); + emit AccountStored({account: account}); + } + + /// @notice Initializes the plugin when the update from build 1 to build 3 is applied. + /// @dev The initialization of `SimpleStorageBuild1` has already happened. + function initializeFromBuild1(address _account) external reinitializer(3) { + account = _account; + + emit NumberStored({number: number}); + emit AccountStored({account: _account}); + } + + function storeNumber(uint256 _number) external auth(STORE_NUMBER_PERMISSION_ID) { + if (_number == number) revert AlreadyStored(); + + number = _number; + + emit NumberStored({number: _number}); + } + + function storeAccount(address _account) external auth(STORE_ACCOUNT_PERMISSION_ID) { + if (_account == account) revert AlreadyStored(); + + account = _account; + + emit AccountStored({account: _account}); + } +} +``` + +NOTE: Despite no storage-related changes happening in build 3, we must apply the `reinitializer(3)` modifier to all `initialize` functions so that +none of them can be called twice or in the wrong order. + + +// TODO merge this sections and clean up redundancy \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-plugin-contract.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-plugin-contract.adoc new file mode 100644 index 000000000..4d0f4c834 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-plugin-contract.adoc @@ -0,0 +1,185 @@ += Plugin Contract + +// == How to develop Plugin + +This section will be focuses on non-upgradeable plugins development, for upgradeable plugins please check out our xref:guide-develop-plugin/write-upgradeable-plugin.adoc[guide here]. + +Before continuing make sure you've read our documentation on xref:guide-develop-plugin/design-your-plugin.adoc#choosing_the_plugin_upgradeability[Choosing the Best Type for Your Plugin] to make sure you're selecting the right type of contract for your Plugin. + +== How to Initialize the plugin + + +Every plugin should receive and store the address of the DAO it is associated with upon initialization. This is how the plugin will be able to interact with the DAO that has installed it. + +In addition, your plugin implementation might want to introduce other storage variables that should be initialized immediately after the contract was created. +For example, in the `SimpleAdmin` plugin example (which sets one address as the full admin of the DAO), we'd want to store the `admin` +address. + +```solidity +contract SimpleAdmin is Plugin { + address public admin; +} +``` + +The way we set up the plugin's `initialize()` function depends on the plugin type selected. To review plugin types in depth, check out +our xref:guide-develop-plugin/design-your-plugin.adoc#choosing_the_plugin_upgradeability[guide here]. + +Additionally, the way we deploy our contracts is directly correlated with how they're initialized. For Non-Upgradeable Plugins, +there's two ways in which we can deploy our plugin: + +- Deployment via Solidity's `new` keyword, OR +- Deployment via the Minimal Proxy Pattern + +### Option A: Deployment via Solidity's `new` Keyword + +To instantiate the contract via Solidity's `new` keyword, you should inherit from the `Plugin` Base Template Aragon created. +You can find it link:https://github.com/aragon/osx-commons/blob/develop/contracts/src/plugin/Plugin.sol[here]. + +In this case, the compiler will force you to write a `constructor` function calling the `Plugin` parent `constructor` and +provide it with a contract of type `IDAO`. Inside the constructor, you might want to initialize the storage variables that you have +added yourself, such as the `admin` address in the example below. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.21; + +import {Plugin, IDAO} from '@aragon/osx/core/plugin/Plugin.sol'; + +contract SimpleAdmin is Plugin { + address public immutable admin; + + /// @notice Initializes the contract. + /// @param _dao The associated DAO. + /// @param _admin The address of the admin. + constructor(IDAO _dao, address _admin) Plugin(_dao) { + admin = _admin; + } +} +``` + +NOTE: The `admin` variable is set as `immutable` so that it can never be changed. Immutable variables can only be initialized in +the constructor. + +This type of constructor implementation stores the `IDAO _dao` reference in the right place. If your plugin is deployed often, which we could expect, we can link:https://blog.openzeppelin.com/workshop-recap-cheap-contract-deployment-through-clones/[save significant amounts of gas by deployment through using the minimal proxy pattern]. + +### Option B: Deployment via the Minimal Proxy Pattern + +To deploy our plugin via the link:https://eips.ethereum.org/EIPS/eip-1167(minimal clones pattern (ERC-1167)), you inherit from the `PluginCloneable` contract introducing the same features as `Plugin`. +The only difference is that you now have to remember to write an `initialize` function. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.21; + +import {PluginCloneable, IDAO} from '@aragon/osx/core/plugin/PluginCloneable.sol'; + +contract SimpleAdmin is PluginCloneable { + address public admin; + + /// @notice Initializes the contract. + /// @param _dao The associated DAO. + /// @param _admin The address of the admin. + function initialize(IDAO _dao, address _admin) external initializer { + __PluginCloneable_init(_dao); + admin = _admin; + } +} +``` + +We must protect it from being called multiple times by using link:https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable[OpenZeppelin's `initializer` modifier made available through `Initializable`] and +call the internal function `__PluginCloneable_init(IDAO _dao)` available through the `PluginCloneable` base contract to +store the `IDAO _dao` reference in the right place. + +CAUTION: If you forget calling `__PluginCloneable_init(_dao)` inside your `initialize` function, your plugin won't be associated +with a DAO and cannot use the DAO's `PermissionManager`. + + + + +== How to Build a the plugin + +Once we've initialized our plugin (take a look at our guide on xref:how_to_initialize_the_plugin[how to initialize the plugin here]), +we can start using the Non-Upgradeable Base Template to perform actions on the DAO. + +### 1. Set the Permission Identifier + +Firstly, we want to define a xref:core/permissions.adoc#permission_identifiers[permission identifier] `bytes32` constant at the top +of the contract and establish a `keccak256` hash of the permission name we want to choose. +In this example, we're calling it the `ADMIN_EXECUTE_PERMISSION`. + +```solidity +contract SimpleAdmin is PluginCloneable { + /// @notice The ID of the permission required to call the `execute` function. + bytes32 public constant ADMIN_EXECUTE_PERMISSION_ID = keccak256('ADMIN_EXECUTE_PERMISSION'); + + address public admin; + + /// @notice Initializes the contract. + /// @param _dao The associated DAO. + /// @param _admin The address of the admin. + function initialize(IDAO _dao, address _admin) external initializer { + __PluginCloneable_init(_dao); + admin = _admin; + } + + /// @notice Executes actions in the associated DAO. + function execute(IDAO.Action[] calldata _actions) external auth(ADMIN_EXECUTE_PERMISSION_ID) { + revert('Not implemented.'); + } +} +``` + +NOTE: +You are free to choose the permission name however you like. For example, you could also have used `keccak256('SIMPLE_ADMIN_PLUGIN:PERMISSION_1')`. +However, it is important that the permission names are descriptive and cannot be confused with each other. + +Setting this permission is key because it ensures only signers who have been granted that permission are able to execute functions. + +### 2. Add the logic implementation + +Now that we have created the permission, we will use it to protect the implementation. We want to make sure only the authorized callers holding the `ADMIN_EXECUTE_PERMISSION`, can use the function. + +Because we have initialized the link:https://github.com/aragon/osx-commons/blob/develop/contracts/src/plugin/PluginCloneable.sol[`PluginCloneable` base contract], +we can now use its features, i.e., the link:https://github.com/aragon/osx-commons/blob/1cf46ff15dbda8481f9ee37558e7ea8b257d51f2/contracts/src/permission/auth/DaoAuthorizable.sol#L30-L35[auth modifier] +provided through the `DaoAuthorizable` base class. The `auth('ADMIN_EXECUTE_PERMISSION')` returns an error if the address calling +on the function has not been granted that permission, effectively protecting from malicious use cases. + +Later, we will also use the link:https://github.com/aragon/osx-commons/blob/1cf46ff15dbda8481f9ee37558e7ea8b257d51f2/contracts/src/permission/auth/DaoAuthorizable.sol#L24-L28[dao() getter function from the base contract], +which returns the associated DAO for that plugin. + +```solidity +contract SimpleAdmin is PluginCloneable { + /// @notice The ID of the permission required to call the `execute` function. + bytes32 public constant ADMIN_EXECUTE_PERMISSION_ID = keccak256('ADMIN_EXECUTE_PERMISSION'); + + address public admin; + + /// @notice Initializes the contract. + /// @param _dao The associated DAO. + /// @param _admin The address of the admin. + function initialize(IDAO _dao, address _admin) external initializer { + __PluginCloneable_init(_dao); + admin = _admin; + } + + /// @notice Executes actions in the associated DAO. + /// @param _actions The actions to be executed by the DAO. + function execute(IDAO.Action[] calldata _actions) external auth(ADMIN_EXECUTE_PERMISSION_ID) { + dao().execute({callId: 0x0, actions: _actions, allowFailureMap: 0}); + } +} +``` + +NOTE: In this example, we are building a governance plugin. To increase its capabilities and provide some standardization into the protocol, we recommend completing the governance plugin by +xref:guide-develop-plugin/design-your-plugin#how_to_build_a_governance_plugin[implementing the `IProposal` and `IMembership` interfaces]. +Optionally, you can also allow certain actions to fail by using xref:core/actions.adoc#allowing_for_failure[the failure map feature of the DAO executor]. + +For now, we used default values for the `callId` and `allowFailureMap` parameters required by the DAO's `execute` function. +With this, the plugin implementation could be used and deployed already. Feel free to add any additional logic to +your plugin's capabilities here. + +### 3. Plugin done, Setup contract next! + +Now that we have the logic for the plugin implemented, we'll need to define how this plugin should be installed/uninstalled from a DAO. +In the next step, we'll write the `PluginSetup` contract - the one containing the installation, uninstallation, and +upgrading instructions for the plugin. diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-plugin-setup-contract.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-plugin-setup-contract.adoc new file mode 100644 index 000000000..ea9f4dae2 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-plugin-setup-contract.adoc @@ -0,0 +1,337 @@ += Plugin Setup Contract + +== What is the Plugin Setup contract? + +The Plugin Setup contract is the contract defining the instructions for installing, uninstalling, or upgrading plugins into DAOs. This contract prepares the permission granting or revoking that needs to happen in order for plugins to be able to perform actions on behalf of the DAO. + +You need it for the plugin to be installed into the DAO. + +### 1. Finish the Plugin contract + +Before building your Plugin Setup contract, make sure you have the logic for your plugin implemented. In this case, we're building a simple admin plugin which grants one address permission to execute actions on behalf of the DAO. + +```solidity +contract SimpleAdmin is PluginCloneable { + /// @notice The ID of the permission required to call the `execute` function. + bytes32 public constant ADMIN_EXECUTE_PERMISSION_ID = keccak256('ADMIN_EXECUTE_PERMISSION'); + + address public admin; + + /// @notice Initializes the contract. + /// @param _dao The associated DAO. + /// @param _admin The address of the admin. + function initialize(IDAO _dao, address _admin) external initializer { + __PluginCloneable_init(_dao); + admin = _admin; + } + + /// @notice Executes actions in the associated DAO. + /// @param _actions The actions to be executed by the DAO. + function execute(IDAO.Action[] calldata _actions) external auth(ADMIN_EXECUTE_PERMISSION_ID) { + dao().execute({_callId: 0x0, _actions: _actions, _allowFailureMap: 0}); + } +} +``` + +### 2. How to initialize the Plugin Setup contract + +Each `PluginSetup` contract is deployed only once and we will publish a separate `PluginSetup` instance for each version. Accordingly, we instantiate the `implementation` contract via Solidity's `new` keyword as deployment with the minimal proxy pattern would be more expensive in this case. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.21; + +import {PluginSetup, IPluginSetup} from '@aragon/osx/framework/plugin/setup/PluginSetup.sol'; +import {SimpleAdmin} from './SimpleAdmin.sol'; + +contract SimpleAdminSetup is PluginSetup { + /// @notice The address of `SimpleAdmin` plugin contract to be cloned. + address private immutable simpleAdminImplementation; + + /// @notice The constructor setting the `SimpleAdmin` implementation contract to clone from. + constructor() { + simpleAdminImplementation = address(new SimpleAdmin()); + } + + /// @inheritdoc IPluginSetup + function implementation() external view returns (address) { + return simpleAdminImplementation; + } +} +``` + +### 3. Build the Skeleton + +In order for the Plugin to be easily installed into the DAO, we need to define the permissions the plugin will need. + +We will create a `prepareInstallation()` function, as well as a `prepareUninstallation()` function. These are the functions the `PluginSetupProcessor.sol` (the contract in charge of installing plugins into the DAO) will use to prepare the installation/uninstallation of the plugin into the DAO. + +For example, a skeleton for our `SimpleAdminSetup` contract inheriting from `PluginSetup` looks as follows: + +```solidity +import {PermissionLib} from '@aragon/osx/core/permission/PermissionLib.sol'; + +contract SimpleAdminSetup is PluginSetup { + /// @notice The address of `SimpleAdmin` plugin logic contract to be cloned. + address private immutable simpleAdminImplementation; + + /// @notice The constructor setting the `SimpleAdmin` implementation contract to clone from. + constructor() { + simpleAdminImplementation = address(new SimpleAdmin()); + } + + /// @inheritdoc IPluginSetup + function prepareInstallation( + address _dao, + bytes calldata _data + ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + revert('Not implemented yet.'); + } + + /// @inheritdoc IPluginSetup + function prepareUninstallation( + address _dao, + SetupPayload calldata _payload + ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + revert('Not implemented yet.'); + } + + /// @inheritdoc IPluginSetup + function implementation() external view returns (address) { + return simpleAdminImplementation; + } +} +``` + +As you can see, we have a constructor storing the implementation contract instantiated via the `new` method in the private immutable variable `implementation` to save gas and a `implementation` function to retrieve it. + +Next, we will add the implementation for the `prepareInstallation` and `prepareUninstallation` functions. + +### 4. Implementing the `prepareInstallation()` function + +The `prepareInstallation()` function should take in two parameters: + +1. the `DAO` it prepares the installation for, and +2. the `_data` parameter containing all the information needed for this function to work properly, in this case, the address we want to set as admin of our DAO. + +Hence, the first thing we should do when working on the `prepareInstallation()` function is decode the information from the `_data` parameter. We also want to check that the address is not accidentally set to `address(0)`, which would freeze the DAO forever. + +```solidity +import {Clones} from '@openzeppelin/contracts/proxy/Clones.sol'; + +contract SimpleAdminSetup is PluginSetup { + using Clones for address; + + /// @notice Thrown if the admin address is zero. + /// @param admin The admin address. + error AdminAddressInvalid(address admin); + + // ... +} +``` + +Then, we will use link:https://docs.openzeppelin.com/contracts/4.x/api/proxy#Clones[OpenZeppelin's `Clones` library] to clone our Plugin contract and initialize it with the `admin` address. The first line, `using Clones for address;`, allows us to call OpenZeppelin `Clones` library to clone contracts deployed at an address. + +The second line introduces a custom error being thrown if the admin address specified is the zero address. + +```solidity +function prepareInstallation( + address _dao, + bytes calldata _data +) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + // Decode `_data` to extract the params needed for cloning and initializing the `Admin` plugin. + address admin = abi.decode(_data, (address)); + + if (admin == address(0)) { + revert AdminAddressInvalid({admin: admin}); + } + + // Clone plugin contract. + plugin = implementation.clone(); + + // Initialize cloned plugin contract. + SimpleAdmin(plugin).initialize(IDAO(_dao), admin); + + // Prepare permissions + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[](2); + + // Grant the `ADMIN_EXECUTE_PERMISSION` of the plugin to the admin. + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: plugin, + who: admin, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleAdmin(plugin).ADMIN_EXECUTE_PERMISSION_ID() + }); + + // Grant the `EXECUTE_PERMISSION` on the DAO to the plugin. + permissions[1] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: _dao, + who: plugin, + condition: PermissionLib.NO_CONDITION, + permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() + }); + + preparedSetupData.permissions = permissions; +} +``` + +Finally, we construct and return an array with the permissions that we need for our plugin to work properly. + +- First, we request granting the `ADMIN_EXECUTE_PERMISSION_ID` to the `admin` address received. This is what gives the address access to use `plugin`'s functionality - in this case, call on the plugin's `execute` function so it can execute actions on behalf of the DAO. +- Second, we request that our newly deployed plugin can use the `EXECUTE_PERMISSION_ID` permission on the `_dao`. We don't add conditions to the permissions in this case, so we use the `NO_CONDITION` constant provided by `PermissionLib`. + +### 5. Implementing the `prepareUninstallation()` function + +For the uninstallation, we have to make sure to revoke the two permissions that have been granted during the installation process. +First, we revoke the `ADMIN_EXECUTE_PERMISSION_ID` from the `admin` address that we have stored in the implementation contract. +Second, we revoke the `EXECUTE_PERMISSION_ID` from the `plugin` address that we obtain from the `_payload` calldata. + +```solidity +function prepareUninstallation( + address _dao, + SetupPayload calldata _payload +) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + // Collect addresses + address plugin = _payload.plugin; + address admin = SimpleAdmin(plugin).admin(); + + // Prepare permissions + permissions = new PermissionLib.MultiTargetPermission[](2); + + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: plugin, + who: admin, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleAdmin(plugin).ADMIN_EXECUTE_PERMISSION_ID() + }); + + permissions[1] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _dao, + who: plugin, + condition: PermissionLib.NO_CONDITION, + permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() + }); +} +``` + +#### 6. Putting Everything Together + +Now, it's time to wrap up everything together. You should have a contract that looks like this: + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.21; + +import {Clones} from '@openzeppelin/contracts/proxy/Clones.sol'; + +import {PermissionLib} from '@aragon/osx/core/permission/PermissionLib.sol'; +import {PluginSetup, IPluginSetup} from '@aragon/osx/framework/plugin/setup/PluginSetup.sol'; +import {SimpleAdmin} from './SimpleAdmin.sol'; + +contract SimpleAdminSetup is PluginSetup { + using Clones for address; + + /// @notice The address of `SimpleAdmin` plugin logic contract to be cloned. + address private immutable simpleAdminImplementation; + + /// @notice Thrown if the admin address is zero. + /// @param admin The admin address. + error AdminAddressInvalid(address admin); + + /// @notice The constructor setting the `Admin` implementation contract to clone from. + constructor() { + simpleAdminImplementation = address(new SimpleAdmin()); + } + + /// @inheritdoc IPluginSetup + function prepareInstallation( + address _dao, + bytes calldata _data + ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + // Decode `_data` to extract the params needed for cloning and initializing the `Admin` plugin. + address admin = abi.decode(_data, (address)); + + if (admin == address(0)) { + revert AdminAddressInvalid({admin: admin}); + } + + // Clone plugin contract. + plugin = implementation.clone(); + + // Initialize cloned plugin contract. + SimpleAdmin(plugin).initialize(IDAO(_dao), admin); + + // Prepare permissions + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[](2); + + // Grant the `ADMIN_EXECUTE_PERMISSION` of the plugin to the admin. + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: plugin, + who: admin, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleAdmin(plugin).ADMIN_EXECUTE_PERMISSION_ID() + }); + + // Grant the `EXECUTE_PERMISSION` on the DAO to the plugin. + permissions[1] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: _dao, + who: plugin, + condition: PermissionLib.NO_CONDITION, + permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() + }); + + preparedSetupData.permissions = permissions; + } + + /// @inheritdoc IPluginSetup + function prepareUninstallation( + address _dao, + SetupPayload calldata _payload + ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + // Collect addresses + address plugin = _payload.plugin; + address admin = SimpleAdmin(plugin).admin(); + + // Prepare permissions + permissions = new PermissionLib.MultiTargetPermission[](2); + + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: plugin, + who: admin, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleAdmin(plugin).ADMIN_EXECUTE_PERMISSION_ID() + }); + + permissions[1] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _dao, + who: plugin, + condition: PermissionLib.NO_CONDITION, + permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() + }); + } + + /// @inheritdoc IPluginSetup + function implementation() external view returns (address) { + return simpleAdminImplementation; + } +} +``` + +Once done, our plugin is ready to be published on the Aragon plugin registry. With the address of the `SimpleAdminSetup` contract, we are ready for creating our `PluginRepo`, the plugin's repository where all plugin versions will live. +Check out our how to guides on xref:guide-develop-plugin/publishing-plugin.adoc[publishing your plugin here]. + +### In the future: Subsequent Builds + +For subsequent builds or releases of your plugin, you'll simply write a new implementation and associated Plugin Setup contract providing a new `prepareInstallation` and `prepareUninstallation` function. + +If a DAO wants to install the new build or release, it must uninstall its current plugin and freshly install the new plugin version, which can happen in the same action array in a governance proposal. However, the plugin storage and event history will be lost since this is a non-upgradeable plugin. If you want to prevent the latter, you can learn xref:guide-develop-plugin/write-upgradeable-plugin.adoc[how to write an upgradeable plugin here]. diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-upgradeable-plugin.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-upgradeable-plugin.adoc new file mode 100644 index 000000000..e4b64afca --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-develop-plugin/write-upgradeable-plugin.adoc @@ -0,0 +1,356 @@ += Writing an Upgradeable Plugin + +Upgradeable contracts offer advantages because you can cheaply change or fix the logic of your contract without losing the storage of your contract. +If you want to review plugin types in depth, check out our xref:guide-develop-plugin/design-your-plugin.adoc#choosing_the_plugin_upgradeability[guide on plugin types here]. + +The drawbacks however, are that: + +- there are plenty of ways to make a mistake, and +- the changeable logic poses a new attack surface. + +Although we've abstracted away most of the complications of the upgrade process through our `PluginUUPSUpgradeable` base class, +please know that writing an upgradeable contract is an advanced topic. + +Developing upgradeable plugins can be challenging, ensure you are familiar with link:https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable[Upgradeable contracts development] before you start. + + +== How to Initialize Upgradeable Plugins + +To deploy your implementation contract via the link:https://eips.ethereum.org/EIPS/eip-1822[UUPS pattern (ERC-1822)], you inherit from the `PluginUUPSUpgradeable` contract. + +We must protect it from being set up multiple times by using link:https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable[OpenZeppelin's initializer modifier made available through Initializable]. +In order to do this, we will call the internal function `__PluginUUPSUpgradeable_init(IDAO _dao)` function available through the `PluginUUPSUpgradeable` +base contract to store the `IDAO _dao` reference in the right place. + +NOTE: This has to be called - otherwise, anyone else could call the plugin's initialization with whatever params they wanted. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.21; + +import {PluginUUPSUpgradeable, IDAO} '@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol'; + +/// @title SimpleStorage build 1 +contract SimpleStorageBuild1 is PluginUUPSUpgradeable { + uint256 public number; // added in build 1 + + /// @notice Initializes the plugin when build 1 is installed. + function initializeBuild1(IDAO _dao, uint256 _number) external initializer { + __PluginUUPSUpgradeable_init(_dao); + number = _number; + } +} +``` + +NOTE: Keep in mind that in order to discriminate between the different initialize functions of your different builds, +we name the initialize function `initializeBuild1`. This becomes more demanding for subsequent builds of your plugin. + +### Initializing Subsequent Builds + +Since you have chosen to build an upgradeable plugin, you can publish subsequent builds of plugin and **allow the users to +update from an earlier build without losing the storage**. + +CAUTION: Do not inherit from previous versions as this can mess up the inheritance chain. Instead, write self-contained +contracts by simply copying the code or modifying the file in your git repo. + +In this example, we wrote a `SimpleStorageBuild2` contract and added a new storage variable `address public account;`. +Because users can freshly install the new version or update from build 1, we now have to write two initializer +functions: `initializeBuild2` and `initializeFromBuild1` in our Plugin implementation contract. + +```solidity +/// @title SimpleStorage build 2 +contract SimpleStorageBuild2 is PluginUUPSUpgradeable { + uint256 public number; // added in build 1 + address public account; // added in build 2 + + /// @notice Initializes the plugin when build 2 is installed. + function initializeBuild2( + IDAO _dao, + uint256 _number, + address _account + ) external reinitializer(2) { + __PluginUUPSUpgradeable_init(_dao); + number = _number; + account = _account; + } + + /// @notice Initializes the plugin when the update from build 1 to build 2 is applied. + /// @dev The initialization of `SimpleStorageBuild1` has already happened. + function initializeFromBuild1(IDAO _dao, address _account) external reinitializer(2) { + account = _account; + } +} +``` + +In general, for each version for which you want to support updates from, you have to provide a separate `initializeFromBuildX` +function taking care of initializing the storage and transferring the `helpers` and `permissions` of the previous version into +the same state as if it had been freshly installed. + +Each `initializeBuildX` must be protected with a modifier that allows it to be only called once. + +In contrast to build 1, we now must use link:https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-reinitializer-uint8-[OpenZeppelin's `modifier reinitializer(uint8 build)`] +for build 2 instead of `modifier initializer` because it allows us to execute 255 subsequent initializations. +More specifically, we used `reinitializer(2)` here for our build 2. Note that we could also have used +`function initializeBuild1(IDAO _dao, uint256 _number) external reinitializer(1)` for build 1 because +`initializer` and `reinitializer(1)` are equivalent statements. For build 3, we must use `reinitializer(3)`, +for build 4 `reinitializer(4)` and so on. + + +== How to build an Upgradeable Plugin implementation contract + +In this guide, we'll build a `SimpleStorage` Upgradeable plugin which all it does is storing a number. + +The Plugin contract is the one containing all the logic we'd like to implement on the DAO. + +### 1. Set up the initialize function + +Make sure you have the initializer of your plugin well set up. Please review xref:#how_to_initialize_upgradeable_plugins[our guide on how to do that here] if you haven't already. + +Once you this is done, let's dive into several implementations and builds, as can be expected for Upgradeable plugins. + +### 2. Adding your plugin implementation logic + +In our first build, we want to add an authorized `storeNumber` function to the contract - allowing a caller holding the `STORE_PERMISSION_ID` permission to change the stored value similar to what we did for xref:guide-develop-plugin/write-plugin-contract.adoc[the non-upgradeable `SimpleAdmin` Plugin]. + +```solidity +import {PluginUUPSUpgradeable, IDAO} '@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol'; + +/// @title SimpleStorage build 1 +contract SimpleStorageBuild1 is PluginUUPSUpgradeable { + bytes32 public constant STORE_PERMISSION_ID = keccak256('STORE_PERMISSION'); + + uint256 public number; // added in build 1 + + /// @notice Initializes the plugin when build 1 is installed. + function initializeBuild1(IDAO _dao, uint256 _number) external initializer { + __PluginUUPSUpgradeable_init(_dao); + number = _number; + } + + function storeNumber(uint256 _number) external auth(STORE_PERMISSION_ID) { + number = _number; + } +} +``` + +### 3. Plugin done, PluginSetup contract next! + +Now that we have the logic for the plugin implemented, we'll need to define how this plugin should be installed/uninstalled from a DAO. In the next step, we'll write the `PluginSetup` contract - the one containing the installation, uninstallation, and upgrading instructions for the plugin. + + +// TODO set up contract should be very similar to non-upgradeable plugin setup contract check this section and minimize redundancy +// todo consider sorting this differently if after cleaning/merging/phrasing this file is still too long + +== How to build the Plugin Setup Contract for Upgradeable Plugins + +The Plugin Setup contract is the contract defining the instructions for installing, uninstalling, or upgrading plugins into DAOs. +This contract prepares the permission granting or revoking that needs to happen in order for plugins to be able to perform +actions on behalf of the DAO. + +### 1. Finish the Plugin contract's first build + +Before building the Plugin Setup contract, make sure you have the logic for your plugin implemented. In this case, + we're building a simple storage plugin which stores a number. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.21; + +import {IDAO, PluginUUPSUpgradeable} from '@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol'; + +/// @title SimpleStorage build 1 +contract SimpleStorageBuild1 is PluginUUPSUpgradeable { + bytes32 public constant STORE_PERMISSION_ID = keccak256('STORE_PERMISSION'); + + uint256 public number; // added in build 1 + + /// @notice Initializes the plugin when build 1 is installed. + function initializeBuild1(IDAO _dao, uint256 _number) external initializer { + __PluginUUPSUpgradeable_init(_dao); + number = _number; + } + + function storeNumber(uint256 _number) external auth(STORE_PERMISSION_ID) { + number = _number; + } +} +``` + +### 2. Add the `prepareInstallation()` and `prepareUninstallation()` functions + +Each `PluginSetup` contract is deployed only once and each plugin version will have its own `PluginSetup` contract deployed. +Accordingly, we instantiate the `implementation` contract via Solidity's `new` keyword as deployment with the minimal proxy +pattern would be more expensive in this case. + +In order for the Plugin to be easily installed into the DAO, we need to define the instructions for the plugin to work effectively. +We have to tell the DAO's Permission Manager which permissions it needs to grant or revoke. + +Hence, we will create a `prepareInstallation()` function, as well as a `prepareUninstallation()` function. These are the functions +the `PluginSetupProcessor.sol` (the contract in charge of installing plugins into the DAO) will use. + +The `prepareInstallation()` function takes in two parameters: + +1. the `DAO` it should prepare the installation for, and +2. the `_data` parameter containing all the information needed for this function to work properly, encoded as a `bytes memory`. +In this case, we get the number we want to store. + +Hence, the first thing we should do when working on the `prepareInstallation()` function is decode the information from the `_data` parameter. +Similarly, the `prepareUninstallation()` function takes in a `payload`. + +```solidity +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.21; + +import {PermissionLib} from '@aragon/osx/core/permission/PermissionLib.sol'; +import {PluginSetup, IPluginSetup} from '@aragon/osx/framework/plugin/setup/PluginSetup.sol'; +import {SimpleStorageBuild1} from './SimpleStorageBuild1.sol'; + +/// @title SimpleStorageSetup build 1 +contract SimpleStorageBuild1Setup is PluginSetup { + address private immutable simpleStorageImplementation; + + constructor() { + simpleStorageImplementation = address(new SimpleStorageBuild1()); + } + + /// @inheritdoc IPluginSetup + function prepareInstallation( + address _dao, + bytes memory _data + ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + uint256 number = abi.decode(_data, (uint256)); + + plugin = createERC1967Proxy( + simpleStorageImplementation, + abi.encodeCall(SimpleStorageBuild1.initializeBuild1, (IDAO(_dao), number)) + ); + + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[](1); + + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Grant, + where: plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleStorageBuild1(this.implementation()).STORE_PERMISSION_ID() + }); + + preparedSetupData.permissions = permissions; + } + + /// @inheritdoc IPluginSetup + function prepareUninstallation( + address _dao, + SetupPayload calldata _payload + ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + permissions = new PermissionLib.MultiTargetPermission[](1); + + permissions[0] = PermissionLib.MultiTargetPermission({ + operation: PermissionLib.Operation.Revoke, + where: _payload.plugin, + who: _dao, + condition: PermissionLib.NO_CONDITION, + permissionId: SimpleStorageBuild1(this.implementation()).STORE_PERMISSION_ID() + }); + } + + /// @inheritdoc IPluginSetup + function implementation() external view returns (address) { + return simpleStorageImplementation; + } +} +``` + +As you can see, we have a constructor storing the implementation contract instantiated via the `new` method in the private immutable +variable `implementation` to save gas and an `implementation` function to return it. + +NOTE: Specifically important for this type of plugin is the `prepareUpdate()` function. Since we don't know the parameters we will require when updating the plugin to the next version, we can't add the `prepareUpdate()` function just yet. However, keep in mind that we will need to deploy new Plugin Setup contracts in subsequent builds to add in the `prepareUpdate()` function with each build requirements. +We see this in depth in the xref:guide-develop-plugin/upgrade-plugin.adoc[How to update an Upgradeable Plugin] section. + +### 3. Deployment + +Once you're done with your Plugin Setup contract, we'll need to deploy it so we can publish it into the Aragon OSx protocol. +You can deploy your contract with a basic deployment script. + +Firstly, we'll make sure our preferred network is well setup within our `hardhat.config.js` file, which should look something like: + +```js +import '@nomicfoundation/hardhat-toolbox'; + +// To find your Alchemy key, go to https://dashboard.alchemy.com/. Infura or any other provider would work here as well. +const goerliAlchemyKey = 'add-your-own-alchemy-key'; +// To find a private key, go to your wallet of choice and export a private key. Remember this must be kept secret at all times. +const privateKeyGoerli = 'add-your-account-private-key'; + +module.exports = { + defaultNetwork: 'hardhat', + networks: { + hardhat: {}, + goerli: { + url: `https://eth-goerli.g.alchemy.com/v2/${goerliAlchemyKey}`, + accounts: [privateKeyGoerli], + }, + }, + solidity: { + version: '0.8.17', + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + paths: { + sources: './contracts', + tests: './test', + cache: './cache', + artifacts: './artifacts', + }, + mocha: { + timeout: 40000, + }, +}; +``` + +Then, create a `scripts/deploy.js` file and add a simple deploy script. We'll only be deploying the PluginSetup contract, +since this should deploy the Plugin contract within its constructor. + +```js +import {ethers} from 'hardhat'; + +async function main() { + const [deployer] = await ethers.getSigners(); + + console.log('Deploying contracts with the account:', deployer.address); + console.log('Account balance:', (await deployer.getBalance()).toString()); + + const getSimpleStorageSetup = + await ethers.getContractFactory('SimpleStorageSetup'); + const SimpleStorageSetup = await SimpleStorageSetup.deploy(); + + await SimpleStorageSetup.deployed(); + + console.log('SimpleStorageSetup address:', SimpleStorageSetup.address); +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +main().catch(error => { + console.error(error); + process.exitCode = 1; +}); +``` + +Finally, run this in your terminal to execute the command: + +```bash +npx hardhat run scripts/deploy.ts +``` + +### 4. Publishing the Plugin to the Aragon OSx Protocol + +Once done, our plugin is ready to be published on the Aragon plugin registry. With the address of the `SimpleAdminSetup` +contract deployed, we're almost ready for creating our `PluginRepo`, the plugin's repository where all plugin versions will live. +Check out our how to guides on xref:guide-develop-plugin/publishing-plugin.adoc[publishing your plugin here]. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/core/permissions/conditions.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/custom-permission-condition.adoc similarity index 100% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/core/permissions/conditions.adoc rename to packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/custom-permission-condition.adoc diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/execute-actions.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/execute-actions.adoc new file mode 100644 index 000000000..0750f09e9 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/execute-actions.adoc @@ -0,0 +1,145 @@ += Executing actions on behalf of the DAO + +## Using the DAO Executor + +Executing actions on behalf of the DAO is done through the `execute` function from the `DAO.sol` contract. This function allows us to link:https://github.com/aragon/osx/blob/develop/packages/contracts/src/core/dao/DAO.sol[pass an array of actions] to be executed by the DAO contract itself. + +However, for the `execute` call to work, the address calling the function (the `msg.sender`) needs to have the xref:core/permissions.adoc#permissions_native_to_the_dao_contract[`EXECUTE_PERMISSION`]. This is to prevent anyone from being able to execute actions on behalf of the DAO and keep your assets safe from malicious actors. + +## How to grant the Execute Permission + +Usually, the `EXECUTE_PERMISSION` is granted to a governance plugin of the DAO so that only the approved proposals can be executed. For example, we'd grant the `EXECUTE_PERMISSION` to the address of the Multisig Plugin. That way, when a proposal is approved by the required members of the multisig, the plugin is able to call the `execute` function on the DAO in order to get the actions executed. + +To grant the `EXECUTE_PERMISSION` to an address, you'll want to call on the `PermissionManager`'s link:https://github.com/aragon/osx/blob/develop/packages/contracts/src/core/permission/PermissionManager.sol#L105[grant function] and pass it 4 parameters: + +- `where`: the address of the contract containing the function `who` wants access to +- `who`: the address (EOA or contract) receiving the permission +- `permissionId`: the permission identifier the caller needs to have in order to be able to execute the action +- `condition`: the address of the condition contract that will be asked (if any) before authorizing the call to happen + +CAUTION: You probably don't want to grant `EXECUTE_PERMISSION` to any random address, since this gives the address access to execute any action on behalf of the DAO. We recommend you only grant `EXECUTE_PERMISSION` to governance plugins to ensure the safety of your assets. Granting `EXECUTE_PERMISSION` to an externally owned account is considered an anti-pattern. + +## Examples + +### Calling a DAO Function + +Imagine you want to call an internal function inside the `DAO` contract, for example, to manually xref:core/permissions.adoc[grant or revoke a permission]. The corresponding `Action` and `execute` function call look as follows: + +```solidity +function exampleGrantCall( + DAO dao, + bytes32 _callId, + address _where, + address _who, + bytes32 _permissionId +) { + // Create the action array + IDAO.Action[] memory actions = new IDAO.Action[](1); + actions[0] = IDAO.Action({ + to: address(dao), + value: 0, + data: abi.encodeWithSelector(PermissionManager.grant.selector, _where, _who, _permissionId) + }); + + // Execute the action array + (bytes[] memory execResults, ) = dao.execute({ + _callId: _callId, + _actions: actions, + _allowFailureMap: 0 + }); +} +``` + +Here we use the selector of the xref:api:core.adoc#PermissionManager-grant-address-address-bytes32-[`grant` function]. +To revoke the permission, the selector of the xref:api:core.adoc#PermissionManager-revoke-address-address-bytes32-[`revoke` function] + +If the caller possesses the xref:core/permissions.adoc#permissions_native_to_the_dao_contract[`ROOT_PERMISSION_ID` permission] on the DAO contract, the call becomes simpler and cheaper: + +CAUTION: Granting the `ROOT_PERMISSION_ID` permission to other contracts other than the `DAO` contract is dangerous and considered as an anti-pattern. + +```solidity +function exampleGrantFunction(DAO dao, address _where, address _who, bytes32 _permissionId) { + dao.grant(_where, _who, _permissionId); // For this to work, the `msg.sender` needs the `ROOT_PERMISSION_ID` +} +``` + +### Sending Native Tokens + +Send `0.1 ETH` from the DAO treasury to Alice. +The corresponding `Action` and `execute` function call would look as follows: + +```solidity +function exampleNativeTokenTransfer(IDAO dao, bytes32 _callId, address _receiver) { + // Create the action array + IDAO.Action[] memory actions = new IDAO.Action[](1); + + actions[0] = IDAO.Action({to: _receiver, value: 0.1 ether, data: ''}); + + // Execute the action array + dao.execute({_callId: _callId, _actions: actions, _allowFailureMap: 0}); +} +``` + +### Calling a Function from an External Contract + +Imagine that you want to call an external function, let's say in a `Calculator` contract that adds two numbers for you. The corresponding `Action` and `execute` function call look as follows: + +```solidity +contract ICalculator { + function add(uint256 _a, uint256 _b) external pure returns (uint256 sum); +} + +function exampleFunctionCall( + IDAO dao, + bytes32 _callId, + ICalculator _calculator, + uint256 _a, + uint256 _b +) { + // Create the action array + IDAO.Action[] memory actions = new IDAO.Action[](1); + actions[0] = IDAO.Action({ + to: address(_calculator), + value: 0, // 0 native tokens must be sent with this call + data: abi.encodeCall(_calculator.add, (_a, _b)) + }); + + // Execute the action array + (bytes[] memory execResults, ) = dao.execute({ + _callId: _callId, + _actions: actions, + _allowFailureMap: 0 + }); + + // Decode the action results + uint256 sum = abi.decode(execResults[0], (uint256)); // the result of `add(_a,_b)` +} +``` + +### Calling a Payable Function + +Wrap `0.1 ETH` from the DAO treasury into `wETH` by depositing it into the link:https://goerli.etherscan.io/token/0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6#writeContract[Goerli WETH9 contract]. +The corresponding `Action` and `execute` function call look as follows: + +```solidity +interface IWETH9 { + function deposit() external payable; + + function withdraw(uint256 _amount) external; +} + +function examplePayableFunctionCall(IDAO dao, bytes32 _callId, IWETH9 _wethToken) { + // Create the action array + + IDAO.Action[] memory actions = new IDAO.Action[](1); + + actions[0] = IDAO.Action({ + to: address(_wethToken), + value: 0.1 ether, + data: abi.encodeCall(IWETH9.deposit, ()) + }); + + // Execute the action array + dao.execute({_callId: _callId, _actions: actions, _allowFailureMap: 0}); +} +``` diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/index.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/index.adoc new file mode 100644 index 000000000..bd10b753c --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/index.adoc @@ -0,0 +1,20 @@ += How to Operate a DAO + +DAOs are decentralized autonomous organizations. They are a group of people managing on-chain assets through a set of smart contracts. + +## What do you need to know in order to operate your DAO? + +DAOs manage assets through collective decision-making mechanisms. Although a lot can be said of the social, behavioral aspects of operating a DAO, in this guide we will focus on the technical aspects. + +In Aragon OSx, DAOs are a treasury and a permission management system - all other functionality is enabled through "capsules of opt-in functionality allowing the DAO to work in custom ways". These are called Plugins. + +NOTE: Plugins are smart contracts which extend the functionality of what the DAO can do. They are able to execute actions on behalf of the DAO through permissions the DAO grants or revokes them. + +Decision-making mechanisms are one example of Plugins. Treasury management, action bundles, or connections to other smart contracts are others. + +In this section, we'll go through how to operate and maintain your DAO: + +- xref:how-to-guides/dao/best-practices.adoc[A Summary of Best Practices] +- xref:how-to-guides/dao/action-execution.adoc[How to execute actions on behalf of the DAO] +- xref:how-to-guides/dao/managing-plugins.adoc[How to manage a DAO's plugins] +- xref:how-to-guides/dao/protocol-upgrades.adoc[How to upgrade your DAO to a future Aragon OSx Releases] diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-setup/security-risk-mitigation.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/keep-dao-safe.adoc similarity index 58% rename from packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-setup/security-risk-mitigation.adoc rename to packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/keep-dao-safe.adoc index 1b3433eeb..9ee9f914f 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-setup/security-risk-mitigation.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/keep-dao-safe.adoc @@ -1,6 +1,23 @@ ---- -title: Plugin Security and Risks ---- += Best Practices + +=== Some Advice When Operating your DAO + +### DOs 👌 + +- Make sure that at least one address (typically a governance plugin) has `EXECUTE_PERMISSION_ID` permission so that something can be executed on behalf of the DAO. +- Check every proposal asking to install, update, or uninstall a plugin with utmost care and review. Installation means granting an external contract permissions to do things on behalf of your DAO, so you want to be extra careful about: + - the implementation contract + - the setup contract + - the helper contracts + - the permissions being granted/revoked + +### DON'Ts ✋ + +- Incapacitate your DAO by revoking all `EXECUTE_PERMISSION`. This means your DAO will be blocked and any assets you hold may be locked in forever. This can happen through: + - uninstalling your last governance plugin. + - applying an update to your last governance plugin. +- Don't give permissions to directly call functions from the DAO. Better and safer to use a plugin instead. +- If you're using the Token Voting plugin in your DAO, make sure you don't mint additional tokens without careful consideration. If you mint too many at once, this may lock your DAO, since you will not be able to reach the minimum participation threshold. This happens if there are not enough tokens already on the market to meet the minimum participation percentage and the DAO owns most of the governance tokens. ## Risks and Their Mitigation @@ -22,14 +39,13 @@ that might be carelessly or intentionally caused, a malicious plugin can hide ** #### Backdoors -- [metamorphic contracts](https://a16zcrypto.com/metamorphic-smart-contract-detector-tool/) (contracts, that can be redeployed with new code to the same address) +- link:https://a16zcrypto.com/metamorphic-smart-contract-detector-tool[metamorphic contracts] (contracts, that can be redeployed with new code to the same address) - malicious repurposing of storage in an update of an upgradeable plugin contract - #### Permissions -Examples for elevated permissions, are the [permissions native to the DAO contract](../../../01-core/02-permissions/index.md#permissions-native-to-the-dao-contract) such as +Examples for elevated permissions, are the [permissions native to the DAO contract](../../../01-core/02-permissions/index.md#permissions_native_to_the_dao_contract) such as - `ROOT_PERMISSION_ID` - `EXECUTE_PERMISSION_ID` diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/manage-dao-plugins.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/manage-dao-plugins.adoc new file mode 100644 index 000000000..299875cd0 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/manage-dao-plugins.adoc @@ -0,0 +1,45 @@ += Manage your DAO's Plugins + +== How to manage the Plugins within your DAO + +// + +You can install, uninstall or update any plugin into your DAO. If you want to dive deeper into plugins, check out xref:core/plugins.adoc[how plugins work here]. + +Before diving deeper into this guide, make sure that you understand xref:core/permissions.adoc[permissions] and know about the xref:core/dao.adoc[DAO executor]. + +### How to create a DAO with Plugins + +When you create your DAO, you must **install at least one functioning governance plugin** (meaning one plugin having the `EXECUTION_PERMISSION`) so your have a mechanism of executing actions on behalf of your DAO. +This is crucial because otherwise nobody can operate the DAO and it would become incapacitated right after it was created. You would have spent gas for nothing. + +TIP: If you create your DAO through the link:https://app.aragon.org[Aragon App] or the link:https://devs.aragon.org/docs/sdk[Aragon SDK], this will be checked and you will be warned in case you have not selected a suitable Aragon plugin. + +Although the easiest (and recommended) way to create your DAO is through the link:https://app.aragon.org[Aragon App] or the link:https://devs.aragon.org/docs/sdk[Aragon SDK], you can also do it directly from the protocol through calling on the link:https://github.com/aragon/osx/blob/develop/packages/contracts/src/framework/dao/DAOFactory.sol#L63[`createDAO` function] from the `DAOFactory` contract and passing it the calldata `DAOSettings` for your DAO as well as the `PluginSettings` array referencing the plugins and the settings to be installed upon DAO creation. + +// + +#### How to change a DAO's Governance Setup after a DAO has been created + +After a DAO is created with at least one plugin installed with `EXECUTE_PERMISSION` on the DAO, it's likely you may want to change change your governance setup later on by xref:framework/plugin-setup-processor.adoc[installing, updating, or uninstalling plugins]. + +Here, it is very important that you **maintain at least one functioning governance plugin** (a contract with `EXECUTE_PERMISSION` on the DAO) so that your assets are not locked in the future. In that regard, you want to be careful to not accidentally: + +- uninstall every plugin within your DAO, or +- update or upgrade the plugin or otherwise change the internal plugin settings. + +If you do that, nobody would be able to create proposals and execute actions on the DAO anymore. Accordingly, DAOs must review proposals requesting to change the governance setup with utmost care before voting for them. In the next section, we explain how to review a proposal properly and what to pay attention too. + + + +### How to maintain Execution Permission on the DAO + +A very important thing to consider when operating your DAO is to make sure that you do not lock it - meaning, you allow it into a state where the DAO cannot execute actions anymore. + +The accidental loss of the permission to execute actions on your DAO (xref:core/permissions.adoc#permissions_native_to_the_dao_contract[the `EXECUTION_PERMISSION_ID` permission]) incapacitates your DAO. If this happens, you are not able to withdraw funds or act through the DAO, unless you have the `ROOT_PERMISSION_ID` on the DAO. + + +WARNING: Do not interact directly with the smart contracts unless you know exactly what you are doing, **especially if this involves granting or revoking permissions**. Instead, use the Aragon App or Aragon SDK for creating and managing your DAO and interacting with the smart contracts. + +If you interact with the Aragon OSx protocol through the Aragon App frontend or the Aragon SDK and use only audited and verified plugins, this will not happen. +However, diligence and care is required in some situations. \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/upgrade-dao.adoc b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/upgrade-dao.adoc new file mode 100644 index 000000000..ea6ce5055 --- /dev/null +++ b/packages/contracts/docs/modules/ROOT/pages/guide-set-up-dao/upgrade-dao.adoc @@ -0,0 +1,11 @@ += Upgrade your DAO + +== Upgrading to Future Aragon OSx Protocol Versions + +At Aragon, we are constantly working on improving the Aragon OSx framework. + +To make it easy for your DAO to switch to future Aragon OSx protocol versions, we added the possibility to upgrade our protocol in the future. + +Whenever we provide a new Aragon OSx protocol version, it will be possible to upgrade your DAO and associated plugins through your DAO dashboard. + +link:https://aragondevelopers.substack.com/[Add your email here] if you'd like to receive updates when this happens! \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework-dao.adoc b/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework-dao.adoc index b0fc18f7a..e09152fe5 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework-dao.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework-dao.adoc @@ -7,3 +7,6 @@ To govern the framework infrastructure, a **Framework DAO** was deployed. The Framework DAO controls the permissions of and between the framework-related contracts required to configure and maintain them as well as to replace or upgrade them. This Framework DAO constitutes the **governance layer** of the Aragon OSx DAO Framework. + + +// not added to the nav bar in the first iteration consider adding it in the future \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/index.adoc b/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/index.adoc deleted file mode 100644 index dedeb019c..000000000 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/index.adoc +++ /dev/null @@ -1,19 +0,0 @@ -= Framework - How Everything Connects - -== The Infrastructure Running the Aragon OSx Protocol - -The Aragon OSx protocol is composed of **framework-related contracts** creating and managing the **core contracts**. This includes the - -- xref:how-it-works/framework/dao-creation/index.adoc[Creation of DAOs] and initial plugin configuration -- xref:how-it-works/framework/plugin-management/index.adoc[Management of plugins] which includes the - - - The setup in existing DAOs - - The versioning of different implementations and respective setup contracts, UI, and related metadata - -- xref:how-it-works/framework/ens-names.adoc[Assignment of ENS Names] to `Plugin` and `DAO` contracts created through the framework - -An overview of the involved contracts and their interactions is shown below: - -image::../../../_/images/optimized-svg/framework/aragon-os-infrastructure-core-overview.drawio.svg[align="center"] - -In the following sections, you will learn more about the framework-related contracts of the Aragon OSx protocol. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/index.adoc b/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/index.adoc deleted file mode 100644 index fa8955b7e..000000000 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/index.adoc +++ /dev/null @@ -1,44 +0,0 @@ -= Plugins - -== Plugins - -As mentioned earlier, plugins built by Aragon and third-party developers can be added and removed from your DAO to adapt it to your needs. - -The management of these plugins is handled for you by the Aragon OSx protocol so that the process of - -- Releasing new plugins as well as -- Installing, updating, and uninstalling them to your DAO - -becomes as streamlined as possible. - -In the following, we learn what a plugin consists of. - -### What Does a Plugin Consist Of? - -An Aragon OSx Plugin consists of: - -- The `PluginSetup` contract - - - referencing the `Plugin` implementation internally - - containing the setup instruction to install, update, and uninstall it to an existing DAO - -- A metadata URI pointing to a `JSON` file containing the - - - AragonApp frontend information - - Information needed for the setup ABI - -- A version tag consisting of a - - - Release number - - Build number - -A detailed explanation of the xref:how-to-guides/plugin-development/publication/versioning.adoc[build and release versioning] is found in the How-to sections in our developer portal. - -image::../../../../_/images/optimized-svg/plugins/plugin-version.drawio.svg[align="center"] - -The `PluginSetup` is written by you, the plugin developer. The processing of the setup is managed by the `PluginSetupProcessor`, -the central component of the setup process in the Aragon OSx framework, which is explained -in the section xref:how-it-works/framework/plugin-management/plugin-setup/index.adoc[The Plugin Setup Process]. - -Each plugin with its different builds and releases is versioned inside its own plugin repositories in a `PluginRepo` contract, -which is explained in the next section. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-repo/index.adoc b/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-repo/index.adoc deleted file mode 100644 index 8063b2e30..000000000 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/framework/plugin-management/plugin-repo/index.adoc +++ /dev/null @@ -1,53 +0,0 @@ -= Plugin Repositories - -== What are Plugin Repositories? - -Each plugin has its own Plugin Repository, unique ENS name, and on-chain repository contract, the `PluginRepo`, in which different versions of the plugin are stored for reference using version tags constituted by a **release** and **build** number. - -Different versions might contain: - -- bug fixes -- new features -- breaking changes - -`PluginRepo` contracts themselves, each associated with a different plugin, are registered in the Aragon -OSx xref:how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.adoc#the_pluginreporegistry_contract[PluginRepoRegistry] -and carry their own xrex:how-it-works/framework/ens-names.adoc[ENS name] that the creator chooses. -The xref:how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.adoc#the_pluginreporegistry_contract[PluginRepoRegistry] is described in the upcoming subsection. - -image::../../../../../_/images/optimized-svg/plugins/plugin-repo-overview.drawio.svg[align="center"] - - -### The `PluginRepo` Contract - -The `PluginRepo` contract versions the releases of a `Plugin`. The first version of a plugin is always published as release 1 and build 1 (version tag `1.1`). -When you publish the first plugin version, a new plugin repository is automatically created for you by the Aragon OSx protocol in which you are the maintainer. -The creation process is described in the xref:how-it-works/framework/plugin-management/plugin-repo/plugin-repo-creation.adoc[plugin repo creation process] section. - -The `PluginRepo` contract is link:https://eips.ethereum.org/EIPS/eip-1822[UUPS upgradeable], inherits from the xref:how-it-works/core/permissions/index.adoc[PermissionManager] -and allows the maintainer of the repository to create new versions with the `createVersion` function: - -```solidity" -/// @notice Creates a new plugin version as the latest build for an existing release number or the first build for a new release number for the provided `PluginSetup` contract address and metadata. -/// @param _release The release number. -/// @param _pluginSetupAddress The address of the plugin setup contract. -/// @param _buildMetadata The build metadata URI. -/// @param _releaseMetadata The release metadata URI. -function createVersion( - uint8 _release, - address _pluginSetup, - bytes calldata _buildMetadata, - bytes calldata _releaseMetadata -) external auth(address(this), MAINTAINER_PERMISSION_ID); -``` - -The function receives four input arguments: - -1. The `_release` number to create the build for. If the release number exists already (e.g., release `1`), it is registered as the latest build (e.g., `1.3` if the previous build was `1.2`). If it is a new release number, the build number is `1` (e.g., `2.1`). -2. The address of `PluginSetup` contract internally referencing the implementation contract (to copy, proxy, or clone from it) and taking care of [installing, updating to, and uninstalling](../02-plugin-setup/index.md) this specific version. -3. The `_buildMetadata` URI pointing to a JSON file containing the UI data, setup data, and change description for this specific version. -4. The `_releaseMetadata` URI pointing to a JSON file containing the plugin name, description, as well as optional data such as images to be shown in the aragonApp frontend. - -Other functions present in the contract allow you to query previous versions and to update the release metadata. For more details visit the [`PluginRepo` reference guide entry](../../../../03-reference-guide/framework/plugin/repo/PluginRepo.md). TODO:GIORGI - -The `PluginRepo` is created for you when you publish the `PluginSetup` contract of your first version to the Aragon OSx protocol. \ No newline at end of file diff --git a/packages/contracts/docs/modules/ROOT/pages/how-it-works/index.adoc b/packages/contracts/docs/modules/ROOT/pages/how-it-works/index.adoc deleted file mode 100644 index 0cb242ebe..000000000 --- a/packages/contracts/docs/modules/ROOT/pages/how-it-works/index.adoc +++ /dev/null @@ -1,25 +0,0 @@ -== How It Works - - -## The Aragon OSx DAO Framework - -The Aragon OSx protocol is a DAO framework structured as follows: - -image::../../_/images/aragon-os-framework-overview.drawio.svg[align="center"] - -Overview of the Aragon OSx protocol with its structural components and their responsibilities: the governance layer constituted by the framework DAO, the code layer including the framework and core contracts, which depends on external libraries and services - -### Code Layer - -The foundation of the Aragon OSx protocol is the **code layer** constituted by the core and framework related contracts. -The xref:how-it-works/core/index.adoc[core contracts] provide the core primitives intended to be used by users and implemented by developers of the DAO framework. -The xref:how-it-works/framework/index.adoc[framework contracts] provide the infrastructure to easily create and manage your DAOs and plugins easy. -Both are built on top of external dependencies, most notably the link:https://www.openzeppelin.com/contracts[OpenZeppelin] and the link:https://docs.ens.domains/[Ethereum Name Service (ENS)] contracts. - -The core and framework contracts are free to use, and no additional fees are charged. - -### Governance Layer - -To govern the framework infrastructure, an Aragon OSx [Framework DAO](./03-framwork-dao.md) is deployed constituting the **governance layer** of the Aragon OSx protocol. - -In the next sections, you will learn more about the individual components of the framework. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-to-guides/dao/action-execution.adoc b/packages/contracts/docs/modules/ROOT/pages/how-to-guides/dao/action-execution.adoc index b90092e92..8b5d82950 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-to-guides/dao/action-execution.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/how-to-guides/dao/action-execution.adoc @@ -4,7 +4,7 @@ Executing actions on behalf of the DAO is done through the `execute` function from the `DAO.sol` contract. This function allows us to link:https://github.com/aragon/osx/blob/develop/packages/contracts/src/core/dao/DAO.sol[pass an array of actions] to be executed by the DAO contract itself. -However, for the `execute` call to work, the address calling the function (the `msg.sender`) needs to have the xref:how-it-works/core/permissions/index.adoc#permissions-native-to-the-dao-contract[`EXECUTE_PERMISSION`]. This is to prevent anyone from being able to execute actions on behalf of the DAO and keep your assets safe from malicious actors. +However, for the `execute` call to work, the address calling the function (the `msg.sender`) needs to have the xref:how-it-works/core/permissions/index.adoc#permissions_native_to_the_dao_contract[`EXECUTE_PERMISSION`]. This is to prevent anyone from being able to execute actions on behalf of the DAO and keep your assets safe from malicious actors. ## How to grant the Execute Permission @@ -52,7 +52,7 @@ function exampleGrantCall( Here we use the selector of the TODO:GIORGI [`grant` function](../../03-reference-guide/core/permission/PermissionManager.md#external-function-grant). To revoke the permission, the selector of the [`revoke` function](../../03-reference-guide/core/permission/PermissionManager.md#external-function-revoke) must be used. -If the caller possesses the xref:how-it-works/core/permissions/index.adoc#permissions-native-to-the-dao-contract[`ROOT_PERMISSION_ID` permission] on the DAO contract, the call becomes simpler and cheaper: +If the caller possesses the xref:how-it-works/core/permissions/index.adoc#permissions_native_to_the_dao_contract[`ROOT_PERMISSION_ID` permission] on the DAO contract, the call becomes simpler and cheaper: CAUTION: Granting the `ROOT_PERMISSION_ID` permission to other contracts other than the `DAO` contract is dangerous and considered as an anti-pattern. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-to-guides/dao/managing-plugins.adoc b/packages/contracts/docs/modules/ROOT/pages/how-to-guides/dao/managing-plugins.adoc index d8167dede..0748687e6 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-to-guides/dao/managing-plugins.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/how-to-guides/dao/managing-plugins.adoc @@ -38,7 +38,7 @@ we explain how to review a proposal properly and what to pay attention too. A very important thing to consider when operating your DAO is to make sure that you do not lock it - meaning, you allow it into a state where the DAO cannot execute actions anymore. -The accidental loss of the permission to execute actions on your DAO (xref:how-it-works/core/permissions/index.adoc#permissions-native-to-the-dao-contract[the `EXECUTION_PERMISSION_ID` permission]) incapacitates your DAO. +The accidental loss of the permission to execute actions on your DAO (xref:how-it-works/core/permissions/index.adoc#permissions_native_to_the_dao_contract[the `EXECUTION_PERMISSION_ID` permission]) incapacitates your DAO. If this happens, you are not able to withdraw funds or act through the DAO, unless you have the `ROOT_PERMISSION_ID` on the DAO. IMPORTANT: Do not interact directly with the smart contracts unless you know exactly what you are doing, **especially if this involves granting or revoking permissions**. diff --git a/packages/contracts/docs/modules/ROOT/pages/how-to-guides/index.adoc b/packages/contracts/docs/modules/ROOT/pages/how-to-guides/index.adoc index ca866adaf..4ce65adfb 100644 --- a/packages/contracts/docs/modules/ROOT/pages/how-to-guides/index.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/how-to-guides/index.adoc @@ -33,7 +33,7 @@ On the technical level, plugins are composed of two key contracts: - ⚡️ The Plugin implementation contract: containing all of the logic and functionality for your DAO, and - 👩🏻‍🏫 The Plugin Setup contract: containing the installation, uninstallation and upgrade instructions for your plugin. -image::../../../../../_/images/img/plugins/what_is_a_plugin.png[align="center"] +image::what_is_a_plugin.png[align="center"] Through plugins, we provide a secure, flexible way for on-chain organizations to iterate as they grow. diff --git a/packages/contracts/docs/modules/ROOT/pages/index.adoc b/packages/contracts/docs/modules/ROOT/pages/index.adoc index 0ce790469..1e4bee018 100644 --- a/packages/contracts/docs/modules/ROOT/pages/index.adoc +++ b/packages/contracts/docs/modules/ROOT/pages/index.adoc @@ -20,6 +20,30 @@ To facilitate this, Aragon OSx runs a set of **framework contracts**: - **Plugin repo factory and registry contract:** create and version plugin repositories. - **Plugin Setup Processor contract:** sets up plugins from a plugin repository in a DAO (installation, update, uninstallation). +## The Aragon OSx DAO Framework + +The Aragon OSx protocol is a DAO framework structured as follows: + +image::aragon-os-framework-overview.drawio.svg[align="center"] + +Overview of the Aragon OSx protocol with its structural components and their responsibilities: the governance layer constituted by the framework DAO, the code layer including the framework and core contracts, which depends on external libraries and services + +### Code Layer + +The foundation of the Aragon OSx protocol is the **code layer** constituted by the core and framework related contracts. +The xref:how-it-works/core/index.adoc[core contracts] provide the core primitives intended to be used by users and implemented by developers of the DAO framework. +The xref:how-it-works/framework/index.adoc[framework contracts] provide the infrastructure to easily create and manage your DAOs and plugins easy. +Both are built on top of external dependencies, most notably the link:https://www.openzeppelin.com/contracts[OpenZeppelin] and the link:https://docs.ens.domains/[Ethereum Name Service (ENS)] contracts. + +The core and framework contracts are free to use, and no additional fees are charged. + +### Governance Layer + +To govern the framework infrastructure, an Aragon OSx [Framework DAO](./03-framwork-dao.md) is deployed constituting the **governance layer** of the Aragon OSx protocol. + +In the next sections, you will learn more about the individual components of the framework. + + ## Getting Started Users interact with the Aragon OSx protocol through the link:https://app.aragon.org[Aragon App], link:https://devs.aragon.org/docs/sdk[Aragon SDK] or directly calling on the link:https://github.com/aragon/osx[protocol contracts] - as well as through any third-party projects built using our stack. @@ -76,4 +100,5 @@ This documentation is divided into conceptual and practical sections as well as - Conceptual xref:how-it-works/index.adoc[How It Works articles] explain the architecture behind our protocol. - Practical xref:how-to-guides/index.adoc[How-to Guides] explain how to use and leverage our protocol. -- The TODO:GIORGI [Reference Guide](03-reference-guide/index.md) generated from the NatSpec comments of the latest `@aragon/osx` release documents each individual Solidity contract, function, and variable. +- The xref:api:core.adoc[Core] and xref:api:framework.adoc[Framework], generated from the NatSpec comments of the latest `@aragon/osx` release documents each individual Solidity contract, function, and variable. + diff --git a/packages/contracts/docs/modules/api/nav.adoc b/packages/contracts/docs/modules/api/nav.adoc index 0db99857f..f627df2b5 100644 --- a/packages/contracts/docs/modules/api/nav.adoc +++ b/packages/contracts/docs/modules/api/nav.adoc @@ -1,2 +1,3 @@ .API -* xref:osx-contracts.adoc[Osx Contracts] +* xref:core.adoc[Core] +* xref:framework.adoc[Framework] diff --git a/packages/contracts/docs/modules/api/pages/core.adoc b/packages/contracts/docs/modules/api/pages/core.adoc new file mode 100644 index 000000000..ad47f8bd7 --- /dev/null +++ b/packages/contracts/docs/modules/api/pages/core.adoc @@ -0,0 +1,1121 @@ +:github-icon: pass:[] +:xref-DAO-nonReentrant--: xref:core.adoc#DAO-nonReentrant-- +:xref-DAO-onlyCallAtInitialization--: xref:core.adoc#DAO-onlyCallAtInitialization-- +:xref-DAO-constructor--: xref:core.adoc#DAO-constructor-- +:xref-DAO-initialize-bytes-address-address-string-: xref:core.adoc#DAO-initialize-bytes-address-address-string- +:xref-DAO-initializeFrom-uint8-3--bytes-: xref:core.adoc#DAO-initializeFrom-uint8-3--bytes- +:xref-DAO-isPermissionRestrictedForAnyAddr-bytes32-: xref:core.adoc#DAO-isPermissionRestrictedForAnyAddr-bytes32- +:xref-DAO-_authorizeUpgrade-address-: xref:core.adoc#DAO-_authorizeUpgrade-address- +:xref-DAO-setTrustedForwarder-address-: xref:core.adoc#DAO-setTrustedForwarder-address- +:xref-DAO-getTrustedForwarder--: xref:core.adoc#DAO-getTrustedForwarder-- +:xref-DAO-hasPermission-address-address-bytes32-bytes-: xref:core.adoc#DAO-hasPermission-address-address-bytes32-bytes- +:xref-DAO-setMetadata-bytes-: xref:core.adoc#DAO-setMetadata-bytes- +:xref-DAO-execute-bytes32-struct-Action---uint256-: xref:core.adoc#DAO-execute-bytes32-struct-Action---uint256- +:xref-DAO-deposit-address-uint256-string-: xref:core.adoc#DAO-deposit-address-uint256-string- +:xref-DAO-setSignatureValidator-address-: xref:core.adoc#DAO-setSignatureValidator-address- +:xref-DAO-isValidSignature-bytes32-bytes-: xref:core.adoc#DAO-isValidSignature-bytes32-bytes- +:xref-DAO-receive--: xref:core.adoc#DAO-receive-- +:xref-DAO-fallback-bytes-: xref:core.adoc#DAO-fallback-bytes- +:xref-DAO-_setMetadata-bytes-: xref:core.adoc#DAO-_setMetadata-bytes- +:xref-DAO-_setTrustedForwarder-address-: xref:core.adoc#DAO-_setTrustedForwarder-address- +:xref-DAO-registerStandardCallback-bytes4-bytes4-bytes4-: xref:core.adoc#DAO-registerStandardCallback-bytes4-bytes4-bytes4- +:xref-DAO-daoURI--: xref:core.adoc#DAO-daoURI-- +:xref-DAO-setDaoURI-string-: xref:core.adoc#DAO-setDaoURI-string- +:xref-DAO-_setDaoURI-string-: xref:core.adoc#DAO-_setDaoURI-string- +:xref-DAO-EXECUTE_PERMISSION_ID-bytes32: xref:core.adoc#DAO-EXECUTE_PERMISSION_ID-bytes32 +:xref-DAO-UPGRADE_DAO_PERMISSION_ID-bytes32: xref:core.adoc#DAO-UPGRADE_DAO_PERMISSION_ID-bytes32 +:xref-DAO-SET_METADATA_PERMISSION_ID-bytes32: xref:core.adoc#DAO-SET_METADATA_PERMISSION_ID-bytes32 +:xref-DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32: xref:core.adoc#DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32 +:xref-DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32: xref:core.adoc#DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32 +:xref-DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32: xref:core.adoc#DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32 +:xref-CallbackHandler-_handleCallback-bytes4-bytes-: xref:core.adoc#CallbackHandler-_handleCallback-bytes4-bytes- +:xref-CallbackHandler-_registerCallback-bytes4-bytes4-: xref:core.adoc#CallbackHandler-_registerCallback-bytes4-bytes4- +:xref-PermissionManager-__PermissionManager_init-address-: xref:core.adoc#PermissionManager-__PermissionManager_init-address- +:xref-PermissionManager-grant-address-address-bytes32-: xref:core.adoc#PermissionManager-grant-address-address-bytes32- +:xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition- +:xref-PermissionManager-revoke-address-address-bytes32-: xref:core.adoc#PermissionManager-revoke-address-address-bytes32- +:xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---: xref:core.adoc#PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission--- +:xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---: xref:core.adoc#PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission--- +:xref-PermissionManager-isGranted-address-address-bytes32-bytes-: xref:core.adoc#PermissionManager-isGranted-address-address-bytes32-bytes- +:xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-: xref:core.adoc#PermissionManager-_checkCondition-address-address-address-bytes32-bytes- +:xref-PermissionManager-_initializePermissionManager-address-: xref:core.adoc#PermissionManager-_initializePermissionManager-address- +:xref-PermissionManager-_grant-address-address-bytes32-: xref:core.adoc#PermissionManager-_grant-address-address-bytes32- +:xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition- +:xref-PermissionManager-_revoke-address-address-bytes32-: xref:core.adoc#PermissionManager-_revoke-address-address-bytes32- +:xref-PermissionManager-_auth-bytes32-: xref:core.adoc#PermissionManager-_auth-bytes32- +:xref-PermissionManager-permissionHash-address-address-bytes32-: xref:core.adoc#PermissionManager-permissionHash-address-address-bytes32- +:xref-PermissionManager-ROOT_PERMISSION_ID-bytes32: xref:core.adoc#PermissionManager-ROOT_PERMISSION_ID-bytes32 +:xref-DAO-NewURI-string-: xref:core.adoc#DAO-NewURI-string- +:xref-CallbackHandler-CallbackReceived-address-bytes4-bytes-: xref:core.adoc#CallbackHandler-CallbackReceived-address-bytes4-bytes- +:xref-PermissionManager-Granted-bytes32-address-address-address-address-: xref:core.adoc#PermissionManager-Granted-bytes32-address-address-address-address- +:xref-PermissionManager-Revoked-bytes32-address-address-address-: xref:core.adoc#PermissionManager-Revoked-bytes32-address-address-address- +:xref-DAO-ReentrantCall--: xref:core.adoc#DAO-ReentrantCall-- +:xref-DAO-TooManyActions--: xref:core.adoc#DAO-TooManyActions-- +:xref-DAO-ActionFailed-uint256-: xref:core.adoc#DAO-ActionFailed-uint256- +:xref-DAO-InsufficientGas--: xref:core.adoc#DAO-InsufficientGas-- +:xref-DAO-ZeroAmount--: xref:core.adoc#DAO-ZeroAmount-- +:xref-DAO-NativeTokenDepositAmountMismatch-uint256-uint256-: xref:core.adoc#DAO-NativeTokenDepositAmountMismatch-uint256-uint256- +:xref-DAO-ProtocolVersionUpgradeNotSupported-uint8-3--: xref:core.adoc#DAO-ProtocolVersionUpgradeNotSupported-uint8-3-- +:xref-DAO-FunctionRemoved--: xref:core.adoc#DAO-FunctionRemoved-- +:xref-DAO-AlreadyInitialized--: xref:core.adoc#DAO-AlreadyInitialized-- +:xref-CallbackHandler-UnknownCallback-bytes4-bytes4-: xref:core.adoc#CallbackHandler-UnknownCallback-bytes4-bytes4- +:xref-PermissionManager-Unauthorized-address-address-bytes32-: xref:core.adoc#PermissionManager-Unauthorized-address-address-bytes32- +:xref-PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-: xref:core.adoc#PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address- +:xref-PermissionManager-ConditionNotAContract-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-ConditionNotAContract-contract-IPermissionCondition- +:xref-PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition- +:xref-PermissionManager-PermissionsForAnyAddressDisallowed--: xref:core.adoc#PermissionManager-PermissionsForAnyAddressDisallowed-- +:xref-PermissionManager-AnyAddressDisallowedForWhoAndWhere--: xref:core.adoc#PermissionManager-AnyAddressDisallowedForWhoAndWhere-- +:xref-PermissionManager-GrantWithConditionNotSupported--: xref:core.adoc#PermissionManager-GrantWithConditionNotSupported-- +:xref-DAO-MAX_ACTIONS-uint256: xref:core.adoc#DAO-MAX_ACTIONS-uint256 +:xref-CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4-: xref:core.adoc#CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4- +:xref-CallbackHandler-UNREGISTERED_CALLBACK-bytes4: xref:core.adoc#CallbackHandler-UNREGISTERED_CALLBACK-bytes4 +:xref-PermissionManager-ANY_ADDR-address: xref:core.adoc#PermissionManager-ANY_ADDR-address +:xref-PermissionManager-UNSET_FLAG-address: xref:core.adoc#PermissionManager-UNSET_FLAG-address +:xref-PermissionManager-ALLOW_FLAG-address: xref:core.adoc#PermissionManager-ALLOW_FLAG-address +:xref-PermissionManager-permissionsHashed-mapping-bytes32----address-: xref:core.adoc#PermissionManager-permissionsHashed-mapping-bytes32----address- +:xref-PermissionManager-auth-bytes32-: xref:core.adoc#PermissionManager-auth-bytes32- +:xref-PermissionManager-__PermissionManager_init-address-: xref:core.adoc#PermissionManager-__PermissionManager_init-address- +:xref-PermissionManager-grant-address-address-bytes32-: xref:core.adoc#PermissionManager-grant-address-address-bytes32- +:xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition- +:xref-PermissionManager-revoke-address-address-bytes32-: xref:core.adoc#PermissionManager-revoke-address-address-bytes32- +:xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---: xref:core.adoc#PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission--- +:xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---: xref:core.adoc#PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission--- +:xref-PermissionManager-isGranted-address-address-bytes32-bytes-: xref:core.adoc#PermissionManager-isGranted-address-address-bytes32-bytes- +:xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-: xref:core.adoc#PermissionManager-_checkCondition-address-address-address-bytes32-bytes- +:xref-PermissionManager-_initializePermissionManager-address-: xref:core.adoc#PermissionManager-_initializePermissionManager-address- +:xref-PermissionManager-_grant-address-address-bytes32-: xref:core.adoc#PermissionManager-_grant-address-address-bytes32- +:xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition- +:xref-PermissionManager-_revoke-address-address-bytes32-: xref:core.adoc#PermissionManager-_revoke-address-address-bytes32- +:xref-PermissionManager-_auth-bytes32-: xref:core.adoc#PermissionManager-_auth-bytes32- +:xref-PermissionManager-permissionHash-address-address-bytes32-: xref:core.adoc#PermissionManager-permissionHash-address-address-bytes32- +:xref-PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-: xref:core.adoc#PermissionManager-isPermissionRestrictedForAnyAddr-bytes32- +:xref-PermissionManager-ROOT_PERMISSION_ID-bytes32: xref:core.adoc#PermissionManager-ROOT_PERMISSION_ID-bytes32 +:xref-PermissionManager-Granted-bytes32-address-address-address-address-: xref:core.adoc#PermissionManager-Granted-bytes32-address-address-address-address- +:xref-PermissionManager-Revoked-bytes32-address-address-address-: xref:core.adoc#PermissionManager-Revoked-bytes32-address-address-address- +:xref-PermissionManager-Unauthorized-address-address-bytes32-: xref:core.adoc#PermissionManager-Unauthorized-address-address-bytes32- +:xref-PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-: xref:core.adoc#PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address- +:xref-PermissionManager-ConditionNotAContract-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-ConditionNotAContract-contract-IPermissionCondition- +:xref-PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition- +:xref-PermissionManager-PermissionsForAnyAddressDisallowed--: xref:core.adoc#PermissionManager-PermissionsForAnyAddressDisallowed-- +:xref-PermissionManager-AnyAddressDisallowedForWhoAndWhere--: xref:core.adoc#PermissionManager-AnyAddressDisallowedForWhoAndWhere-- +:xref-PermissionManager-GrantWithConditionNotSupported--: xref:core.adoc#PermissionManager-GrantWithConditionNotSupported-- +:xref-PermissionManager-ANY_ADDR-address: xref:core.adoc#PermissionManager-ANY_ADDR-address +:xref-PermissionManager-UNSET_FLAG-address: xref:core.adoc#PermissionManager-UNSET_FLAG-address +:xref-PermissionManager-ALLOW_FLAG-address: xref:core.adoc#PermissionManager-ALLOW_FLAG-address +:xref-PermissionManager-permissionsHashed-mapping-bytes32----address-: xref:core.adoc#PermissionManager-permissionsHashed-mapping-bytes32----address- +:xref-CallbackHandler-_handleCallback-bytes4-bytes-: xref:core.adoc#CallbackHandler-_handleCallback-bytes4-bytes- +:xref-CallbackHandler-_registerCallback-bytes4-bytes4-: xref:core.adoc#CallbackHandler-_registerCallback-bytes4-bytes4- +:xref-CallbackHandler-CallbackReceived-address-bytes4-bytes-: xref:core.adoc#CallbackHandler-CallbackReceived-address-bytes4-bytes- +:xref-CallbackHandler-UnknownCallback-bytes4-bytes4-: xref:core.adoc#CallbackHandler-UnknownCallback-bytes4-bytes4- +:xref-CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4-: xref:core.adoc#CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4- +:xref-CallbackHandler-UNREGISTERED_CALLBACK-bytes4: xref:core.adoc#CallbackHandler-UNREGISTERED_CALLBACK-bytes4 += OSX + +This is the reference guide of the link:https://github.com/aragon/osx[osx contracts] package. + +== Core + +:EXECUTE_PERMISSION_ID: pass:normal[xref:#DAO-EXECUTE_PERMISSION_ID-bytes32[`++EXECUTE_PERMISSION_ID++`]] +:UPGRADE_DAO_PERMISSION_ID: pass:normal[xref:#DAO-UPGRADE_DAO_PERMISSION_ID-bytes32[`++UPGRADE_DAO_PERMISSION_ID++`]] +:SET_METADATA_PERMISSION_ID: pass:normal[xref:#DAO-SET_METADATA_PERMISSION_ID-bytes32[`++SET_METADATA_PERMISSION_ID++`]] +:SET_TRUSTED_FORWARDER_PERMISSION_ID: pass:normal[xref:#DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32[`++SET_TRUSTED_FORWARDER_PERMISSION_ID++`]] +:REGISTER_STANDARD_CALLBACK_PERMISSION_ID: pass:normal[xref:#DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32[`++REGISTER_STANDARD_CALLBACK_PERMISSION_ID++`]] +:VALIDATE_SIGNATURE_PERMISSION_ID: pass:normal[xref:#DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32[`++VALIDATE_SIGNATURE_PERMISSION_ID++`]] +:MAX_ACTIONS: pass:normal[xref:#DAO-MAX_ACTIONS-uint256[`++MAX_ACTIONS++`]] +:ReentrantCall: pass:normal[xref:#DAO-ReentrantCall--[`++ReentrantCall++`]] +:TooManyActions: pass:normal[xref:#DAO-TooManyActions--[`++TooManyActions++`]] +:ActionFailed: pass:normal[xref:#DAO-ActionFailed-uint256-[`++ActionFailed++`]] +:InsufficientGas: pass:normal[xref:#DAO-InsufficientGas--[`++InsufficientGas++`]] +:ZeroAmount: pass:normal[xref:#DAO-ZeroAmount--[`++ZeroAmount++`]] +:NativeTokenDepositAmountMismatch: pass:normal[xref:#DAO-NativeTokenDepositAmountMismatch-uint256-uint256-[`++NativeTokenDepositAmountMismatch++`]] +:ProtocolVersionUpgradeNotSupported: pass:normal[xref:#DAO-ProtocolVersionUpgradeNotSupported-uint8-3--[`++ProtocolVersionUpgradeNotSupported++`]] +:FunctionRemoved: pass:normal[xref:#DAO-FunctionRemoved--[`++FunctionRemoved++`]] +:AlreadyInitialized: pass:normal[xref:#DAO-AlreadyInitialized--[`++AlreadyInitialized++`]] +:NewURI: pass:normal[xref:#DAO-NewURI-string-[`++NewURI++`]] +:nonReentrant: pass:normal[xref:#DAO-nonReentrant--[`++nonReentrant++`]] +:onlyCallAtInitialization: pass:normal[xref:#DAO-onlyCallAtInitialization--[`++onlyCallAtInitialization++`]] +:constructor: pass:normal[xref:#DAO-constructor--[`++constructor++`]] +:initialize: pass:normal[xref:#DAO-initialize-bytes-address-address-string-[`++initialize++`]] +:initializeFrom: pass:normal[xref:#DAO-initializeFrom-uint8-3--bytes-[`++initializeFrom++`]] +:isPermissionRestrictedForAnyAddr: pass:normal[xref:#DAO-isPermissionRestrictedForAnyAddr-bytes32-[`++isPermissionRestrictedForAnyAddr++`]] +:_authorizeUpgrade: pass:normal[xref:#DAO-_authorizeUpgrade-address-[`++_authorizeUpgrade++`]] +:setTrustedForwarder: pass:normal[xref:#DAO-setTrustedForwarder-address-[`++setTrustedForwarder++`]] +:getTrustedForwarder: pass:normal[xref:#DAO-getTrustedForwarder--[`++getTrustedForwarder++`]] +:hasPermission: pass:normal[xref:#DAO-hasPermission-address-address-bytes32-bytes-[`++hasPermission++`]] +:setMetadata: pass:normal[xref:#DAO-setMetadata-bytes-[`++setMetadata++`]] +:execute: pass:normal[xref:#DAO-execute-bytes32-struct-Action---uint256-[`++execute++`]] +:deposit: pass:normal[xref:#DAO-deposit-address-uint256-string-[`++deposit++`]] +:setSignatureValidator: pass:normal[xref:#DAO-setSignatureValidator-address-[`++setSignatureValidator++`]] +:isValidSignature: pass:normal[xref:#DAO-isValidSignature-bytes32-bytes-[`++isValidSignature++`]] +:receive: pass:normal[xref:#DAO-receive--[`++receive++`]] +:fallback: pass:normal[xref:#DAO-fallback-bytes-[`++fallback++`]] +:_setMetadata: pass:normal[xref:#DAO-_setMetadata-bytes-[`++_setMetadata++`]] +:_setTrustedForwarder: pass:normal[xref:#DAO-_setTrustedForwarder-address-[`++_setTrustedForwarder++`]] +:registerStandardCallback: pass:normal[xref:#DAO-registerStandardCallback-bytes4-bytes4-bytes4-[`++registerStandardCallback++`]] +:daoURI: pass:normal[xref:#DAO-daoURI--[`++daoURI++`]] +:setDaoURI: pass:normal[xref:#DAO-setDaoURI-string-[`++setDaoURI++`]] +:_setDaoURI: pass:normal[xref:#DAO-_setDaoURI-string-[`++_setDaoURI++`]] + +[.contract] +[[DAO]] +=== `++DAO++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/core/dao/DAO.sol[{github-icon},role=heading-link] + +Public API of the Aragon DAO framework. + +[.contract-index] +.Modifiers +-- +* {xref-DAO-nonReentrant--}[`++nonReentrant()++`] +* {xref-DAO-onlyCallAtInitialization--}[`++onlyCallAtInitialization()++`] + +-- + +[.contract-index] +.Functions +-- +* {xref-DAO-constructor--}[`++constructor()++`] +* {xref-DAO-initialize-bytes-address-address-string-}[`++initialize(_metadata, _initialOwner, _trustedForwarder, daoURI_)++`] +* {xref-DAO-initializeFrom-uint8-3--bytes-}[`++initializeFrom(_previousProtocolVersion, _initData)++`] +* {xref-DAO-isPermissionRestrictedForAnyAddr-bytes32-}[`++isPermissionRestrictedForAnyAddr(_permissionId)++`] +* {xref-DAO-_authorizeUpgrade-address-}[`++_authorizeUpgrade()++`] +* {xref-DAO-setTrustedForwarder-address-}[`++setTrustedForwarder(_newTrustedForwarder)++`] +* {xref-DAO-getTrustedForwarder--}[`++getTrustedForwarder()++`] +* {xref-DAO-hasPermission-address-address-bytes32-bytes-}[`++hasPermission(_where, _who, _permissionId, _data)++`] +* {xref-DAO-setMetadata-bytes-}[`++setMetadata(_metadata)++`] +* {xref-DAO-execute-bytes32-struct-Action---uint256-}[`++execute(_callId, _actions, _allowFailureMap)++`] +* {xref-DAO-deposit-address-uint256-string-}[`++deposit(_token, _amount, _reference)++`] +* {xref-DAO-setSignatureValidator-address-}[`++setSignatureValidator()++`] +* {xref-DAO-isValidSignature-bytes32-bytes-}[`++isValidSignature(_hash, _signature)++`] +* {xref-DAO-receive--}[`++receive()++`] +* {xref-DAO-fallback-bytes-}[`++fallback(_input)++`] +* {xref-DAO-_setMetadata-bytes-}[`++_setMetadata(_metadata)++`] +* {xref-DAO-_setTrustedForwarder-address-}[`++_setTrustedForwarder(_trustedForwarder)++`] +* {xref-DAO-registerStandardCallback-bytes4-bytes4-bytes4-}[`++registerStandardCallback(_interfaceId, _callbackSelector, _magicNumber)++`] +* {xref-DAO-daoURI--}[`++daoURI()++`] +* {xref-DAO-setDaoURI-string-}[`++setDaoURI(newDaoURI)++`] +* {xref-DAO-_setDaoURI-string-}[`++_setDaoURI(daoURI_)++`] +* {xref-DAO-EXECUTE_PERMISSION_ID-bytes32}[`++EXECUTE_PERMISSION_ID()++`] +* {xref-DAO-UPGRADE_DAO_PERMISSION_ID-bytes32}[`++UPGRADE_DAO_PERMISSION_ID()++`] +* {xref-DAO-SET_METADATA_PERMISSION_ID-bytes32}[`++SET_METADATA_PERMISSION_ID()++`] +* {xref-DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32}[`++SET_TRUSTED_FORWARDER_PERMISSION_ID()++`] +* {xref-DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32}[`++REGISTER_STANDARD_CALLBACK_PERMISSION_ID()++`] +* {xref-DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32}[`++VALIDATE_SIGNATURE_PERMISSION_ID()++`] + +[.contract-subindex-inherited] +.CallbackHandler +* {xref-CallbackHandler-_handleCallback-bytes4-bytes-}[`++_handleCallback(_callbackSelector, _data)++`] +* {xref-CallbackHandler-_registerCallback-bytes4-bytes4-}[`++_registerCallback(_callbackSelector, _magicNumber)++`] + +[.contract-subindex-inherited] +.PermissionManager +* {xref-PermissionManager-__PermissionManager_init-address-}[`++__PermissionManager_init(_initialOwner)++`] +* {xref-PermissionManager-grant-address-address-bytes32-}[`++grant(_where, _who, _permissionId)++`] +* {xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++grantWithCondition(_where, _who, _permissionId, _condition)++`] +* {xref-PermissionManager-revoke-address-address-bytes32-}[`++revoke(_where, _who, _permissionId)++`] +* {xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---}[`++applySingleTargetPermissions(_where, items)++`] +* {xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---}[`++applyMultiTargetPermissions(_items)++`] +* {xref-PermissionManager-isGranted-address-address-bytes32-bytes-}[`++isGranted(_where, _who, _permissionId, _data)++`] +* {xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-}[`++_checkCondition(_condition, _where, _who, _permissionId, _data)++`] +* {xref-PermissionManager-_initializePermissionManager-address-}[`++_initializePermissionManager(_initialOwner)++`] +* {xref-PermissionManager-_grant-address-address-bytes32-}[`++_grant(_where, _who, _permissionId)++`] +* {xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++_grantWithCondition(_where, _who, _permissionId, _condition)++`] +* {xref-PermissionManager-_revoke-address-address-bytes32-}[`++_revoke(_where, _who, _permissionId)++`] +* {xref-PermissionManager-_auth-bytes32-}[`++_auth(_permissionId)++`] +* {xref-PermissionManager-permissionHash-address-address-bytes32-}[`++permissionHash(_where, _who, _permissionId)++`] +* {xref-PermissionManager-ROOT_PERMISSION_ID-bytes32}[`++ROOT_PERMISSION_ID()++`] + +[.contract-subindex-inherited] +.ProtocolVersion +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.IExecutor + +[.contract-subindex-inherited] +.IDAO + +[.contract-subindex-inherited] +.ERC165StorageUpgradeable + +[.contract-subindex-inherited] +.ERC165Upgradeable + +[.contract-subindex-inherited] +.IERC165Upgradeable + +[.contract-subindex-inherited] +.IERC1271 + +[.contract-subindex-inherited] +.Initializable + +[.contract-subindex-inherited] +.IEIP4824 + +-- + +[.contract-index] +.Events +-- +* {xref-DAO-NewURI-string-}[`++NewURI(daoURI)++`] + +[.contract-subindex-inherited] +.CallbackHandler +* {xref-CallbackHandler-CallbackReceived-address-bytes4-bytes-}[`++CallbackReceived(sender, sig, data)++`] + +[.contract-subindex-inherited] +.PermissionManager +* {xref-PermissionManager-Granted-bytes32-address-address-address-address-}[`++Granted(permissionId, here, where, who, condition)++`] +* {xref-PermissionManager-Revoked-bytes32-address-address-address-}[`++Revoked(permissionId, here, where, who)++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.IExecutor +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/executors/IExecutor.sol[Executed] + +[.contract-subindex-inherited] +.IDAO +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[MetadataSet] +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[StandardCallbackRegistered] +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[Deposited] +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[NativeTokenDeposited] +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[TrustedForwarderSet] + +[.contract-subindex-inherited] +.ERC165StorageUpgradeable + +[.contract-subindex-inherited] +.ERC165Upgradeable + +[.contract-subindex-inherited] +.IERC165Upgradeable + +[.contract-subindex-inherited] +.IERC1271 + +[.contract-subindex-inherited] +.Initializable + +[.contract-subindex-inherited] +.IEIP4824 + +-- + +[.contract-index] +.Errors +-- +* {xref-DAO-ReentrantCall--}[`++ReentrantCall()++`] +* {xref-DAO-TooManyActions--}[`++TooManyActions()++`] +* {xref-DAO-ActionFailed-uint256-}[`++ActionFailed(index)++`] +* {xref-DAO-InsufficientGas--}[`++InsufficientGas()++`] +* {xref-DAO-ZeroAmount--}[`++ZeroAmount()++`] +* {xref-DAO-NativeTokenDepositAmountMismatch-uint256-uint256-}[`++NativeTokenDepositAmountMismatch(expected, actual)++`] +* {xref-DAO-ProtocolVersionUpgradeNotSupported-uint8-3--}[`++ProtocolVersionUpgradeNotSupported(protocolVersion)++`] +* {xref-DAO-FunctionRemoved--}[`++FunctionRemoved()++`] +* {xref-DAO-AlreadyInitialized--}[`++AlreadyInitialized()++`] + +[.contract-subindex-inherited] +.CallbackHandler +* {xref-CallbackHandler-UnknownCallback-bytes4-bytes4-}[`++UnknownCallback(callbackSelector, magicNumber)++`] + +[.contract-subindex-inherited] +.PermissionManager +* {xref-PermissionManager-Unauthorized-address-address-bytes32-}[`++Unauthorized(where, who, permissionId)++`] +* {xref-PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-}[`++PermissionAlreadyGrantedForDifferentCondition(where, who, permissionId, currentCondition, newCondition)++`] +* {xref-PermissionManager-ConditionNotAContract-contract-IPermissionCondition-}[`++ConditionNotAContract(condition)++`] +* {xref-PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-}[`++ConditionInterfaceNotSupported(condition)++`] +* {xref-PermissionManager-PermissionsForAnyAddressDisallowed--}[`++PermissionsForAnyAddressDisallowed()++`] +* {xref-PermissionManager-AnyAddressDisallowedForWhoAndWhere--}[`++AnyAddressDisallowedForWhoAndWhere()++`] +* {xref-PermissionManager-GrantWithConditionNotSupported--}[`++GrantWithConditionNotSupported()++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.IExecutor + +[.contract-subindex-inherited] +.IDAO + +[.contract-subindex-inherited] +.ERC165StorageUpgradeable + +[.contract-subindex-inherited] +.ERC165Upgradeable + +[.contract-subindex-inherited] +.IERC165Upgradeable + +[.contract-subindex-inherited] +.IERC1271 + +[.contract-subindex-inherited] +.Initializable + +[.contract-subindex-inherited] +.IEIP4824 + +-- + +[.contract-index] +.Internal Variables +-- +* {xref-DAO-MAX_ACTIONS-uint256}[`++uint256 constant MAX_ACTIONS++`] + +[.contract-subindex-inherited] +.CallbackHandler +* {xref-CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4-}[`++mapping(bytes4 => bytes4) callbackMagicNumbers++`] +* {xref-CallbackHandler-UNREGISTERED_CALLBACK-bytes4}[`++bytes4 constant UNREGISTERED_CALLBACK++`] + +[.contract-subindex-inherited] +.PermissionManager +* {xref-PermissionManager-ANY_ADDR-address}[`++address constant ANY_ADDR++`] +* {xref-PermissionManager-UNSET_FLAG-address}[`++address constant UNSET_FLAG++`] +* {xref-PermissionManager-ALLOW_FLAG-address}[`++address constant ALLOW_FLAG++`] +* {xref-PermissionManager-permissionsHashed-mapping-bytes32----address-}[`++mapping(bytes32 => address) permissionsHashed++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.IExecutor + +[.contract-subindex-inherited] +.IDAO + +[.contract-subindex-inherited] +.ERC165StorageUpgradeable + +[.contract-subindex-inherited] +.ERC165Upgradeable + +[.contract-subindex-inherited] +.IERC165Upgradeable + +[.contract-subindex-inherited] +.IERC1271 + +[.contract-subindex-inherited] +.Initializable + +[.contract-subindex-inherited] +.IEIP4824 + +-- + +[.contract-item] +[[DAO-nonReentrant--]] +==== `[.contract-item-name]#++nonReentrant++#++()++` [.item-kind]#modifier# + +A modifier to protect a function from calling itself, directly or indirectly (reentrancy). + +Currently, this modifier is only applied to the `execute()` function. If this is used multiple times, private `_beforeNonReentrant()` and `_afterNonReentrant()` functions should be created to prevent code duplication. + +[.contract-item] +[[DAO-onlyCallAtInitialization--]] +==== `[.contract-item-name]#++onlyCallAtInitialization++#++()++` [.item-kind]#modifier# + +This ensures that the initialize function cannot be called during the upgrade process. + +[.contract-item] +[[DAO-constructor--]] +==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#public# + +Disables the initializers on the implementation contract to prevent it from being left uninitialized. + +[.contract-item] +[[DAO-initialize-bytes-address-address-string-]] +==== `[.contract-item-name]#++initialize++#++(bytes _metadata, address _initialOwner, address _trustedForwarder, string daoURI_)++` [.item-kind]#external# + +Initializes the DAO by +- setting the reentrancy status variable to `_NOT_ENTERED` +- registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID +- setting the trusted forwarder for meta transactions +- giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). + +This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). + +[.contract-item] +[[DAO-initializeFrom-uint8-3--bytes-]] +==== `[.contract-item-name]#++initializeFrom++#++(uint8[3] _previousProtocolVersion, bytes _initData)++` [.item-kind]#external# + +Initializes the DAO after an upgrade from a previous protocol version. + +[.contract-item] +[[DAO-isPermissionRestrictedForAnyAddr-bytes32-]] +==== `[.contract-item-name]#++isPermissionRestrictedForAnyAddr++#++(bytes32 _permissionId) → bool++` [.item-kind]#internal# + +Decides if the granting permissionId is restricted when `_who == ANY_ADDR` or `_where == ANY_ADDR`. + +By default, every permission is unrestricted and it is the derived contract's responsibility to override it. Note, that the `ROOT_PERMISSION_ID` is included and not required to be set it again. + +[.contract-item] +[[DAO-_authorizeUpgrade-address-]] +==== `[.contract-item-name]#++_authorizeUpgrade++#++(address)++` [.item-kind]#internal# + +Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). + +The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. + +[.contract-item] +[[DAO-setTrustedForwarder-address-]] +==== `[.contract-item-name]#++setTrustedForwarder++#++(address _newTrustedForwarder)++` [.item-kind]#external# + +Setter for the trusted forwarder verifying the meta transaction. + +[.contract-item] +[[DAO-getTrustedForwarder--]] +==== `[.contract-item-name]#++getTrustedForwarder++#++() → address++` [.item-kind]#external# + +Getter for the trusted forwarder verifying the meta transaction. + +[.contract-item] +[[DAO-hasPermission-address-address-bytes32-bytes-]] +==== `[.contract-item-name]#++hasPermission++#++(address _where, address _who, bytes32 _permissionId, bytes _data) → bool++` [.item-kind]#external# + +Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. + +[.contract-item] +[[DAO-setMetadata-bytes-]] +==== `[.contract-item-name]#++setMetadata++#++(bytes _metadata)++` [.item-kind]#external# + +Updates the DAO metadata (e.g., an IPFS hash). + +[.contract-item] +[[DAO-execute-bytes32-struct-Action---uint256-]] +==== `[.contract-item-name]#++execute++#++(bytes32 _callId, struct Action[] _actions, uint256 _allowFailureMap) → bytes[] execResults, uint256 failureMap++` [.item-kind]#external# + +Executes a list of actions. If a zero allow-failure map is provided, a failing action reverts the entire execution. If a non-zero allow-failure map is provided, allowed actions can fail without the entire call being reverted. + +[.contract-item] +[[DAO-deposit-address-uint256-string-]] +==== `[.contract-item-name]#++deposit++#++(address _token, uint256 _amount, string _reference)++` [.item-kind]#external# + +Deposits (native) tokens to the DAO contract with a reference string. + +[.contract-item] +[[DAO-setSignatureValidator-address-]] +==== `[.contract-item-name]#++setSignatureValidator++#++(address)++` [.item-kind]#external# + +Removed function being left here to not corrupt the IDAO interface ID. Any call will revert. + +Introduced in v1.0.0. Removed in v1.4.0. + +[.contract-item] +[[DAO-isValidSignature-bytes32-bytes-]] +==== `[.contract-item-name]#++isValidSignature++#++(bytes32 _hash, bytes _signature) → bytes4++` [.item-kind]#external# + +Checks whether a signature is valid for a provided hash according to [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271). + +Relays the validation logic determining who is allowed to sign on behalf of the DAO to its permission manager. +Caller specific bypassing can be set direct granting (i.e., `grant({_where: dao, _who: specificErc1271Caller, _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID})`). +Caller specific signature validation logic can be set by granting with a `PermissionCondition` (i.e., `grantWithCondition({_where: dao, _who: specificErc1271Caller, _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID, _condition: yourConditionImplementation})`) +Generic signature validation logic can be set for all calling contracts by granting with a `PermissionCondition` to `PermissionManager.ANY_ADDR()` (i.e., `grantWithCondition({_where: dao, _who: PermissionManager.ANY_ADDR(), _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID, _condition: yourConditionImplementation})`). + +[.contract-item] +[[DAO-receive--]] +==== `[.contract-item-name]#++receive++#++()++` [.item-kind]#external# + +Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. + +This call is bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). +Gas cost increases in future hard forks might break this function. As an alternative, [ERC-2930](https://eips.ethereum.org/EIPS/eip-2930)-type transactions using access lists can be employed. + +[.contract-item] +[[DAO-fallback-bytes-]] +==== `[.contract-item-name]#++fallback++#++(bytes _input) → bytes++` [.item-kind]#external# + +Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. + +[.contract-item] +[[DAO-_setMetadata-bytes-]] +==== `[.contract-item-name]#++_setMetadata++#++(bytes _metadata)++` [.item-kind]#internal# + +Emits the MetadataSet event if new metadata is set. + +[.contract-item] +[[DAO-_setTrustedForwarder-address-]] +==== `[.contract-item-name]#++_setTrustedForwarder++#++(address _trustedForwarder)++` [.item-kind]#internal# + +Sets the trusted forwarder on the DAO and emits the associated event. + +[.contract-item] +[[DAO-registerStandardCallback-bytes4-bytes4-bytes4-]] +==== `[.contract-item-name]#++registerStandardCallback++#++(bytes4 _interfaceId, bytes4 _callbackSelector, bytes4 _magicNumber)++` [.item-kind]#external# + +Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. + +[.contract-item] +[[DAO-daoURI--]] +==== `[.contract-item-name]#++daoURI++#++() → string++` [.item-kind]#external# + +A distinct Uniform Resource Identifier (URI) pointing to a JSON object following the "EIP-4824 DAO JSON-LD Schema". This JSON file splits into four URIs: membersURI, proposalsURI, activityLogURI, and governanceURI. The membersURI should point to a JSON file that conforms to the "EIP-4824 Members JSON-LD Schema". The proposalsURI should point to a JSON file that conforms to the "EIP-4824 Proposals JSON-LD Schema". The activityLogURI should point to a JSON file that conforms to the "EIP-4824 Activity Log JSON-LD Schema". The governanceURI should point to a flatfile, normatively a .md file. Each of the JSON files named above can be statically hosted or dynamically-generated. + +[.contract-item] +[[DAO-setDaoURI-string-]] +==== `[.contract-item-name]#++setDaoURI++#++(string newDaoURI)++` [.item-kind]#external# + +Updates the set DAO URI to a new value. + +[.contract-item] +[[DAO-_setDaoURI-string-]] +==== `[.contract-item-name]#++_setDaoURI++#++(string daoURI_)++` [.item-kind]#internal# + +Sets the new [ERC-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI and emits the associated event. + +[.contract-item] +[[DAO-EXECUTE_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++EXECUTE_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `execute` function. + +[.contract-item] +[[DAO-UPGRADE_DAO_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++UPGRADE_DAO_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `_authorizeUpgrade` function. + +[.contract-item] +[[DAO-SET_METADATA_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++SET_METADATA_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `setMetadata` function. + +[.contract-item] +[[DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++SET_TRUSTED_FORWARDER_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `setTrustedForwarder` function. + +[.contract-item] +[[DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++REGISTER_STANDARD_CALLBACK_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `registerStandardCallback` function. + +[.contract-item] +[[DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++VALIDATE_SIGNATURE_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to validate [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signatures. + +[.contract-item] +[[DAO-NewURI-string-]] +==== `[.contract-item-name]#++NewURI++#++(string daoURI)++` [.item-kind]#event# + +Emitted when a new DAO URI is set. + +[.contract-item] +[[DAO-ReentrantCall--]] +==== `[.contract-item-name]#++ReentrantCall++#++()++` [.item-kind]#error# + +Thrown if a call is reentrant. + +[.contract-item] +[[DAO-TooManyActions--]] +==== `[.contract-item-name]#++TooManyActions++#++()++` [.item-kind]#error# + +Thrown if the action array length is larger than `MAX_ACTIONS`. + +[.contract-item] +[[DAO-ActionFailed-uint256-]] +==== `[.contract-item-name]#++ActionFailed++#++(uint256 index)++` [.item-kind]#error# + +Thrown if action execution has failed. + +[.contract-item] +[[DAO-InsufficientGas--]] +==== `[.contract-item-name]#++InsufficientGas++#++()++` [.item-kind]#error# + +Thrown if an action has insufficient gas left. + +[.contract-item] +[[DAO-ZeroAmount--]] +==== `[.contract-item-name]#++ZeroAmount++#++()++` [.item-kind]#error# + +Thrown if the deposit amount is zero. + +[.contract-item] +[[DAO-NativeTokenDepositAmountMismatch-uint256-uint256-]] +==== `[.contract-item-name]#++NativeTokenDepositAmountMismatch++#++(uint256 expected, uint256 actual)++` [.item-kind]#error# + +Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. + +[.contract-item] +[[DAO-ProtocolVersionUpgradeNotSupported-uint8-3--]] +==== `[.contract-item-name]#++ProtocolVersionUpgradeNotSupported++#++(uint8[3] protocolVersion)++` [.item-kind]#error# + +Thrown if an upgrade is not supported from a specific protocol version . + +[.contract-item] +[[DAO-FunctionRemoved--]] +==== `[.contract-item-name]#++FunctionRemoved++#++()++` [.item-kind]#error# + +Thrown when a function is removed but left to not corrupt the interface ID. + +[.contract-item] +[[DAO-AlreadyInitialized--]] +==== `[.contract-item-name]#++AlreadyInitialized++#++()++` [.item-kind]#error# + +Thrown when initialize is called after it has already been executed. + +[.contract-item] +[[DAO-MAX_ACTIONS-uint256]] +==== `uint256 [.contract-item-name]#++MAX_ACTIONS++#` [.item-kind]#internal constant# + +The internal constant storing the maximal action array length. + +:ROOT_PERMISSION_ID: pass:normal[xref:#PermissionManager-ROOT_PERMISSION_ID-bytes32[`++ROOT_PERMISSION_ID++`]] +:ANY_ADDR: pass:normal[xref:#PermissionManager-ANY_ADDR-address[`++ANY_ADDR++`]] +:UNSET_FLAG: pass:normal[xref:#PermissionManager-UNSET_FLAG-address[`++UNSET_FLAG++`]] +:ALLOW_FLAG: pass:normal[xref:#PermissionManager-ALLOW_FLAG-address[`++ALLOW_FLAG++`]] +:permissionsHashed: pass:normal[xref:#PermissionManager-permissionsHashed-mapping-bytes32----address-[`++permissionsHashed++`]] +:Unauthorized: pass:normal[xref:#PermissionManager-Unauthorized-address-address-bytes32-[`++Unauthorized++`]] +:PermissionAlreadyGrantedForDifferentCondition: pass:normal[xref:#PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-[`++PermissionAlreadyGrantedForDifferentCondition++`]] +:ConditionNotAContract: pass:normal[xref:#PermissionManager-ConditionNotAContract-contract-IPermissionCondition-[`++ConditionNotAContract++`]] +:ConditionInterfaceNotSupported: pass:normal[xref:#PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-[`++ConditionInterfaceNotSupported++`]] +:PermissionsForAnyAddressDisallowed: pass:normal[xref:#PermissionManager-PermissionsForAnyAddressDisallowed--[`++PermissionsForAnyAddressDisallowed++`]] +:AnyAddressDisallowedForWhoAndWhere: pass:normal[xref:#PermissionManager-AnyAddressDisallowedForWhoAndWhere--[`++AnyAddressDisallowedForWhoAndWhere++`]] +:GrantWithConditionNotSupported: pass:normal[xref:#PermissionManager-GrantWithConditionNotSupported--[`++GrantWithConditionNotSupported++`]] +:Granted: pass:normal[xref:#PermissionManager-Granted-bytes32-address-address-address-address-[`++Granted++`]] +:Revoked: pass:normal[xref:#PermissionManager-Revoked-bytes32-address-address-address-[`++Revoked++`]] +:auth: pass:normal[xref:#PermissionManager-auth-bytes32-[`++auth++`]] +:__PermissionManager_init: pass:normal[xref:#PermissionManager-__PermissionManager_init-address-[`++__PermissionManager_init++`]] +:grant: pass:normal[xref:#PermissionManager-grant-address-address-bytes32-[`++grant++`]] +:grantWithCondition: pass:normal[xref:#PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-[`++grantWithCondition++`]] +:revoke: pass:normal[xref:#PermissionManager-revoke-address-address-bytes32-[`++revoke++`]] +:applySingleTargetPermissions: pass:normal[xref:#PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---[`++applySingleTargetPermissions++`]] +:applyMultiTargetPermissions: pass:normal[xref:#PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---[`++applyMultiTargetPermissions++`]] +:isGranted: pass:normal[xref:#PermissionManager-isGranted-address-address-bytes32-bytes-[`++isGranted++`]] +:_checkCondition: pass:normal[xref:#PermissionManager-_checkCondition-address-address-address-bytes32-bytes-[`++_checkCondition++`]] +:_initializePermissionManager: pass:normal[xref:#PermissionManager-_initializePermissionManager-address-[`++_initializePermissionManager++`]] +:_grant: pass:normal[xref:#PermissionManager-_grant-address-address-bytes32-[`++_grant++`]] +:_grantWithCondition: pass:normal[xref:#PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-[`++_grantWithCondition++`]] +:_revoke: pass:normal[xref:#PermissionManager-_revoke-address-address-bytes32-[`++_revoke++`]] +:_auth: pass:normal[xref:#PermissionManager-_auth-bytes32-[`++_auth++`]] +:permissionHash: pass:normal[xref:#PermissionManager-permissionHash-address-address-bytes32-[`++permissionHash++`]] +:isPermissionRestrictedForAnyAddr: pass:normal[xref:#PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-[`++isPermissionRestrictedForAnyAddr++`]] + +[.contract] +[[PermissionManager]] +=== `++PermissionManager++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/core/permission/PermissionManager.sol[{github-icon},role=heading-link] + +[.contract-index] +.Modifiers +-- +* {xref-PermissionManager-auth-bytes32-}[`++auth(_permissionId)++`] + +-- + +[.contract-index] +.Functions +-- +* {xref-PermissionManager-__PermissionManager_init-address-}[`++__PermissionManager_init(_initialOwner)++`] +* {xref-PermissionManager-grant-address-address-bytes32-}[`++grant(_where, _who, _permissionId)++`] +* {xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++grantWithCondition(_where, _who, _permissionId, _condition)++`] +* {xref-PermissionManager-revoke-address-address-bytes32-}[`++revoke(_where, _who, _permissionId)++`] +* {xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---}[`++applySingleTargetPermissions(_where, items)++`] +* {xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---}[`++applyMultiTargetPermissions(_items)++`] +* {xref-PermissionManager-isGranted-address-address-bytes32-bytes-}[`++isGranted(_where, _who, _permissionId, _data)++`] +* {xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-}[`++_checkCondition(_condition, _where, _who, _permissionId, _data)++`] +* {xref-PermissionManager-_initializePermissionManager-address-}[`++_initializePermissionManager(_initialOwner)++`] +* {xref-PermissionManager-_grant-address-address-bytes32-}[`++_grant(_where, _who, _permissionId)++`] +* {xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++_grantWithCondition(_where, _who, _permissionId, _condition)++`] +* {xref-PermissionManager-_revoke-address-address-bytes32-}[`++_revoke(_where, _who, _permissionId)++`] +* {xref-PermissionManager-_auth-bytes32-}[`++_auth(_permissionId)++`] +* {xref-PermissionManager-permissionHash-address-address-bytes32-}[`++permissionHash(_where, _who, _permissionId)++`] +* {xref-PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-}[`++isPermissionRestrictedForAnyAddr(_permissionId)++`] +* {xref-PermissionManager-ROOT_PERMISSION_ID-bytes32}[`++ROOT_PERMISSION_ID()++`] + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Events +-- +* {xref-PermissionManager-Granted-bytes32-address-address-address-address-}[`++Granted(permissionId, here, where, who, condition)++`] +* {xref-PermissionManager-Revoked-bytes32-address-address-address-}[`++Revoked(permissionId, here, where, who)++`] + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Errors +-- +* {xref-PermissionManager-Unauthorized-address-address-bytes32-}[`++Unauthorized(where, who, permissionId)++`] +* {xref-PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-}[`++PermissionAlreadyGrantedForDifferentCondition(where, who, permissionId, currentCondition, newCondition)++`] +* {xref-PermissionManager-ConditionNotAContract-contract-IPermissionCondition-}[`++ConditionNotAContract(condition)++`] +* {xref-PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-}[`++ConditionInterfaceNotSupported(condition)++`] +* {xref-PermissionManager-PermissionsForAnyAddressDisallowed--}[`++PermissionsForAnyAddressDisallowed()++`] +* {xref-PermissionManager-AnyAddressDisallowedForWhoAndWhere--}[`++AnyAddressDisallowedForWhoAndWhere()++`] +* {xref-PermissionManager-GrantWithConditionNotSupported--}[`++GrantWithConditionNotSupported()++`] + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Internal Variables +-- +* {xref-PermissionManager-ANY_ADDR-address}[`++address constant ANY_ADDR++`] +* {xref-PermissionManager-UNSET_FLAG-address}[`++address constant UNSET_FLAG++`] +* {xref-PermissionManager-ALLOW_FLAG-address}[`++address constant ALLOW_FLAG++`] +* {xref-PermissionManager-permissionsHashed-mapping-bytes32----address-}[`++mapping(bytes32 => address) permissionsHashed++`] + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-item] +[[PermissionManager-auth-bytes32-]] +==== `[.contract-item-name]#++auth++#++(bytes32 _permissionId)++` [.item-kind]#modifier# + +A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through this permission manager. + +[.contract-item] +[[PermissionManager-__PermissionManager_init-address-]] +==== `[.contract-item-name]#++__PermissionManager_init++#++(address _initialOwner)++` [.item-kind]#internal# + +Initialization method to set the initial owner of the permission manager. + +The initial owner is granted the `ROOT_PERMISSION_ID` permission. + +[.contract-item] +[[PermissionManager-grant-address-address-bytes32-]] +==== `[.contract-item-name]#++grant++#++(address _where, address _who, bytes32 _permissionId)++` [.item-kind]#external# + +Grants permission to an address to call methods in a contract guarded by an auth modifier with the specified permission identifier. + +Requires the `ROOT_PERMISSION_ID` permission. +Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. + +[.contract-item] +[[PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-]] +==== `[.contract-item-name]#++grantWithCondition++#++(address _where, address _who, bytes32 _permissionId, contract IPermissionCondition _condition)++` [.item-kind]#external# + +Grants permission to an address to call methods in a target contract guarded by an auth modifier with the specified permission identifier if the referenced condition permits it. + +Requires the `ROOT_PERMISSION_ID` permission +Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. + +[.contract-item] +[[PermissionManager-revoke-address-address-bytes32-]] +==== `[.contract-item-name]#++revoke++#++(address _where, address _who, bytes32 _permissionId)++` [.item-kind]#external# + +Revokes permission from an address to call methods in a target contract guarded by an auth modifier with the specified permission identifier. + +Requires the `ROOT_PERMISSION_ID` permission. +Note, that revoking permissions with `_who` or `_where` equal to `ANY_ADDR` does not revoke other permissions with specific `_who` and `_where` addresses that exist in parallel. + +[.contract-item] +[[PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---]] +==== `[.contract-item-name]#++applySingleTargetPermissions++#++(address _where, struct PermissionLib.SingleTargetPermission[] items)++` [.item-kind]#external# + +Applies an array of permission operations on a single target contracts `_where`. + +[.contract-item] +[[PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---]] +==== `[.contract-item-name]#++applyMultiTargetPermissions++#++(struct PermissionLib.MultiTargetPermission[] _items)++` [.item-kind]#external# + +Applies an array of permission operations on multiple target contracts `items[i].where`. + +[.contract-item] +[[PermissionManager-isGranted-address-address-bytes32-bytes-]] +==== `[.contract-item-name]#++isGranted++#++(address _where, address _who, bytes32 _permissionId, bytes _data) → bool++` [.item-kind]#public# + +Checks if the caller address has permission on the target contract via a permission identifier and relays the answer to a condition contract if this was declared during the granting process. + +[.contract-item] +[[PermissionManager-_checkCondition-address-address-address-bytes32-bytes-]] +==== `[.contract-item-name]#++_checkCondition++#++(address _condition, address _where, address _who, bytes32 _permissionId, bytes _data) → bool++` [.item-kind]#internal# + +Relays the question if caller address has permission on target contract via a permission identifier to a condition contract. +Checks a condition contract by doing an external call via try/catch. + +If the external call fails, we return `false`. + +[.contract-item] +[[PermissionManager-_initializePermissionManager-address-]] +==== `[.contract-item-name]#++_initializePermissionManager++#++(address _initialOwner)++` [.item-kind]#internal# + +Grants the `ROOT_PERMISSION_ID` permission to the initial owner during initialization of the permission manager. + +[.contract-item] +[[PermissionManager-_grant-address-address-bytes32-]] +==== `[.contract-item-name]#++_grant++#++(address _where, address _who, bytes32 _permissionId)++` [.item-kind]#internal# + +This method is used in the external `grant` method of the permission manager. + +Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. + +[.contract-item] +[[PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-]] +==== `[.contract-item-name]#++_grantWithCondition++#++(address _where, address _who, bytes32 _permissionId, contract IPermissionCondition _condition)++` [.item-kind]#internal# + +This method is used in the external `grantWithCondition` method of the permission manager. + +Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. + +[.contract-item] +[[PermissionManager-_revoke-address-address-bytes32-]] +==== `[.contract-item-name]#++_revoke++#++(address _where, address _who, bytes32 _permissionId)++` [.item-kind]#internal# + +This method is used in the public `revoke` method of the permission manager. + +Note, that revoking permissions with `_who` or `_where` equal to `ANY_ADDR` does not revoke other permissions with specific `_who` and `_where` addresses that might have been granted in parallel. + +[.contract-item] +[[PermissionManager-_auth-bytes32-]] +==== `[.contract-item-name]#++_auth++#++(bytes32 _permissionId)++` [.item-kind]#internal# + +A private function to be used to check permissions on the permission manager contract (`address(this)`) itself. + +[.contract-item] +[[PermissionManager-permissionHash-address-address-bytes32-]] +==== `[.contract-item-name]#++permissionHash++#++(address _where, address _who, bytes32 _permissionId) → bytes32++` [.item-kind]#internal# + +Generates the hash for the `permissionsHashed` mapping obtained from the word "PERMISSION", the contract address, the address owning the permission, and the permission identifier. + +[.contract-item] +[[PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-]] +==== `[.contract-item-name]#++isPermissionRestrictedForAnyAddr++#++(bytes32 _permissionId) → bool++` [.item-kind]#internal# + +Decides if the granting permissionId is restricted when `_who == ANY_ADDR` or `_where == ANY_ADDR`. + +By default, every permission is unrestricted and it is the derived contract's responsibility to override it. Note, that the `ROOT_PERMISSION_ID` is included and not required to be set it again. + +[.contract-item] +[[PermissionManager-ROOT_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++ROOT_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `grant`, `grantWithCondition`, `revoke`, and `bulk` function. + +[.contract-item] +[[PermissionManager-Granted-bytes32-address-address-address-address-]] +==== `[.contract-item-name]#++Granted++#++(bytes32 indexed permissionId, address indexed here, address where, address indexed who, address condition)++` [.item-kind]#event# + +Emitted when a permission `permission` is granted in the context `here` to the address `_who` for the contract `_where`. + +[.contract-item] +[[PermissionManager-Revoked-bytes32-address-address-address-]] +==== `[.contract-item-name]#++Revoked++#++(bytes32 indexed permissionId, address indexed here, address where, address indexed who)++` [.item-kind]#event# + +Emitted when a permission `permission` is revoked in the context `here` from the address `_who` for the contract `_where`. + +[.contract-item] +[[PermissionManager-Unauthorized-address-address-bytes32-]] +==== `[.contract-item-name]#++Unauthorized++#++(address where, address who, bytes32 permissionId)++` [.item-kind]#error# + +Thrown if a call is unauthorized. + +[.contract-item] +[[PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-]] +==== `[.contract-item-name]#++PermissionAlreadyGrantedForDifferentCondition++#++(address where, address who, bytes32 permissionId, address currentCondition, address newCondition)++` [.item-kind]#error# + +Thrown if a permission has been already granted with a different condition. + +This makes sure that condition on the same permission can not be overwriten by a different condition. + +[.contract-item] +[[PermissionManager-ConditionNotAContract-contract-IPermissionCondition-]] +==== `[.contract-item-name]#++ConditionNotAContract++#++(contract IPermissionCondition condition)++` [.item-kind]#error# + +Thrown if a condition address is not a contract. + +[.contract-item] +[[PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-]] +==== `[.contract-item-name]#++ConditionInterfaceNotSupported++#++(contract IPermissionCondition condition)++` [.item-kind]#error# + +Thrown if a condition contract does not support the `IPermissionCondition` interface. + +[.contract-item] +[[PermissionManager-PermissionsForAnyAddressDisallowed--]] +==== `[.contract-item-name]#++PermissionsForAnyAddressDisallowed++#++()++` [.item-kind]#error# + +Thrown for `ROOT_PERMISSION_ID` or `EXECUTE_PERMISSION_ID` permission grants where `who` or `where` is `ANY_ADDR`. + +[.contract-item] +[[PermissionManager-AnyAddressDisallowedForWhoAndWhere--]] +==== `[.contract-item-name]#++AnyAddressDisallowedForWhoAndWhere++#++()++` [.item-kind]#error# + +Thrown for permission grants where `who` and `where` are both `ANY_ADDR`. + +[.contract-item] +[[PermissionManager-GrantWithConditionNotSupported--]] +==== `[.contract-item-name]#++GrantWithConditionNotSupported++#++()++` [.item-kind]#error# + +Thrown if `Operation.GrantWithCondition` is requested as an operation but the method does not support it. + +[.contract-item] +[[PermissionManager-ANY_ADDR-address]] +==== `address [.contract-item-name]#++ANY_ADDR++#` [.item-kind]#internal constant# + +A special address encoding permissions that are valid for any address `who` or `where`. + +[.contract-item] +[[PermissionManager-UNSET_FLAG-address]] +==== `address [.contract-item-name]#++UNSET_FLAG++#` [.item-kind]#internal constant# + +A special address encoding if a permissions is not set and therefore not allowed. + +[.contract-item] +[[PermissionManager-ALLOW_FLAG-address]] +==== `address [.contract-item-name]#++ALLOW_FLAG++#` [.item-kind]#internal constant# + +A special address encoding if a permission is allowed. + +[.contract-item] +[[PermissionManager-permissionsHashed-mapping-bytes32----address-]] +==== `mapping(bytes32 => address) [.contract-item-name]#++permissionsHashed++#` [.item-kind]#internal# + +A mapping storing permissions as hashes (i.e., `permissionHash(where, who, permissionId)`) and their status encoded by an address (unset, allowed, or redirecting to a `PermissionCondition`). + +:callbackMagicNumbers: pass:normal[xref:#CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4-[`++callbackMagicNumbers++`]] +:UNREGISTERED_CALLBACK: pass:normal[xref:#CallbackHandler-UNREGISTERED_CALLBACK-bytes4[`++UNREGISTERED_CALLBACK++`]] +:UnknownCallback: pass:normal[xref:#CallbackHandler-UnknownCallback-bytes4-bytes4-[`++UnknownCallback++`]] +:CallbackReceived: pass:normal[xref:#CallbackHandler-CallbackReceived-address-bytes4-bytes-[`++CallbackReceived++`]] +:_handleCallback: pass:normal[xref:#CallbackHandler-_handleCallback-bytes4-bytes-[`++_handleCallback++`]] +:_registerCallback: pass:normal[xref:#CallbackHandler-_registerCallback-bytes4-bytes4-[`++_registerCallback++`]] + +[.contract] +[[CallbackHandler]] +=== `++CallbackHandler++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/core/utils/CallbackHandler.sol[{github-icon},role=heading-link] + +This callback handling functionality is intended to be used by executor contracts (i.e., `DAO.sol`). + +[.contract-index] +.Functions +-- +* {xref-CallbackHandler-_handleCallback-bytes4-bytes-}[`++_handleCallback(_callbackSelector, _data)++`] +* {xref-CallbackHandler-_registerCallback-bytes4-bytes4-}[`++_registerCallback(_callbackSelector, _magicNumber)++`] + +-- + +[.contract-index] +.Events +-- +* {xref-CallbackHandler-CallbackReceived-address-bytes4-bytes-}[`++CallbackReceived(sender, sig, data)++`] + +-- + +[.contract-index] +.Errors +-- +* {xref-CallbackHandler-UnknownCallback-bytes4-bytes4-}[`++UnknownCallback(callbackSelector, magicNumber)++`] + +-- + +[.contract-index] +.Internal Variables +-- +* {xref-CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4-}[`++mapping(bytes4 => bytes4) callbackMagicNumbers++`] +* {xref-CallbackHandler-UNREGISTERED_CALLBACK-bytes4}[`++bytes4 constant UNREGISTERED_CALLBACK++`] + +-- + +[.contract-item] +[[CallbackHandler-_handleCallback-bytes4-bytes-]] +==== `[.contract-item-name]#++_handleCallback++#++(bytes4 _callbackSelector, bytes _data) → bytes4++` [.item-kind]#internal# + +Handles callbacks to adaptively support ERC standards. + +This function is supposed to be called via `_handleCallback(msg.sig, msg.data)` in the `fallback()` function of the inheriting contract. + +[.contract-item] +[[CallbackHandler-_registerCallback-bytes4-bytes4-]] +==== `[.contract-item-name]#++_registerCallback++#++(bytes4 _callbackSelector, bytes4 _magicNumber)++` [.item-kind]#internal# + +Registers a magic number for a callback function selector. + +[.contract-item] +[[CallbackHandler-CallbackReceived-address-bytes4-bytes-]] +==== `[.contract-item-name]#++CallbackReceived++#++(address sender, bytes4 indexed sig, bytes data)++` [.item-kind]#event# + +Emitted when `_handleCallback` is called. + +[.contract-item] +[[CallbackHandler-UnknownCallback-bytes4-bytes4-]] +==== `[.contract-item-name]#++UnknownCallback++#++(bytes4 callbackSelector, bytes4 magicNumber)++` [.item-kind]#error# + +Thrown if the callback function is not registered. + +[.contract-item] +[[CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4-]] +==== `mapping(bytes4 => bytes4) [.contract-item-name]#++callbackMagicNumbers++#` [.item-kind]#internal# + +A mapping between callback function selectors and magic return numbers. + +[.contract-item] +[[CallbackHandler-UNREGISTERED_CALLBACK-bytes4]] +==== `bytes4 [.contract-item-name]#++UNREGISTERED_CALLBACK++#` [.item-kind]#internal constant# + +The magic number refering to unregistered callbacks. + diff --git a/packages/contracts/docs/modules/api/pages/framework.adoc b/packages/contracts/docs/modules/api/pages/framework.adoc new file mode 100644 index 000000000..26f98c5fe --- /dev/null +++ b/packages/contracts/docs/modules/api/pages/framework.adoc @@ -0,0 +1,1520 @@ +:github-icon: pass:[] +:xref-DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor-: xref:framework.adoc#DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor- +:xref-DAOFactory-supportsInterface-bytes4-: xref:framework.adoc#DAOFactory-supportsInterface-bytes4- +:xref-DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings---: xref:framework.adoc#DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings--- +:xref-DAOFactory-_createDAO-struct-DAOFactory-DAOSettings-: xref:framework.adoc#DAOFactory-_createDAO-struct-DAOFactory-DAOSettings- +:xref-DAOFactory-_setDAOPermissions-address-: xref:framework.adoc#DAOFactory-_setDAOPermissions-address- +:xref-DAOFactory-daoBase-address: xref:framework.adoc#DAOFactory-daoBase-address +:xref-DAOFactory-daoRegistry-contract-DAORegistry: xref:framework.adoc#DAOFactory-daoRegistry-contract-DAORegistry +:xref-DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor: xref:framework.adoc#DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor +:xref-DAOFactory-NoPluginProvided--: xref:framework.adoc#DAOFactory-NoPluginProvided-- +:xref-DAOFactory-ROOT_PERMISSION_ID-bytes32: xref:framework.adoc#DAOFactory-ROOT_PERMISSION_ID-bytes32 +:xref-DAOFactory-UPGRADE_DAO_PERMISSION_ID-bytes32: xref:framework.adoc#DAOFactory-UPGRADE_DAO_PERMISSION_ID-bytes32 +:xref-DAOFactory-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32: xref:framework.adoc#DAOFactory-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32 +:xref-DAOFactory-SET_METADATA_PERMISSION_ID-bytes32: xref:framework.adoc#DAOFactory-SET_METADATA_PERMISSION_ID-bytes32 +:xref-DAOFactory-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32: xref:framework.adoc#DAOFactory-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32 +:xref-DAOFactory-EXECUTE_PERMISSION_ID-bytes32: xref:framework.adoc#DAOFactory-EXECUTE_PERMISSION_ID-bytes32 +:xref-DAOFactory-APPLY_INSTALLATION_PERMISSION_ID-bytes32: xref:framework.adoc#DAOFactory-APPLY_INSTALLATION_PERMISSION_ID-bytes32 +:xref-PluginRepoFactory-constructor-contract-PluginRepoRegistry-: xref:framework.adoc#PluginRepoFactory-constructor-contract-PluginRepoRegistry- +:xref-PluginRepoFactory-supportsInterface-bytes4-: xref:framework.adoc#PluginRepoFactory-supportsInterface-bytes4- +:xref-PluginRepoFactory-createPluginRepo-string-address-: xref:framework.adoc#PluginRepoFactory-createPluginRepo-string-address- +:xref-PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes-: xref:framework.adoc#PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes- +:xref-PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address-: xref:framework.adoc#PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address- +:xref-PluginRepoFactory-_createPluginRepo-string-address-: xref:framework.adoc#PluginRepoFactory-_createPluginRepo-string-address- +:xref-PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry: xref:framework.adoc#PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry +:xref-PluginRepoFactory-pluginRepoBase-address: xref:framework.adoc#PluginRepoFactory-pluginRepoBase-address +:xref-DAORegistry-constructor--: xref:framework.adoc#DAORegistry-constructor-- +:xref-DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-: xref:framework.adoc#DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar- +:xref-DAORegistry-register-contract-IDAO-address-string-: xref:framework.adoc#DAORegistry-register-contract-IDAO-address-string- +:xref-DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32: xref:framework.adoc#DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32 +:xref-DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar: xref:framework.adoc#DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar +:xref-InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4-: xref:framework.adoc#InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4- +:xref-InterfaceBasedRegistry-_authorizeUpgrade-address-: xref:framework.adoc#InterfaceBasedRegistry-_authorizeUpgrade-address- +:xref-InterfaceBasedRegistry-_register-address-: xref:framework.adoc#InterfaceBasedRegistry-_register-address- +:xref-InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32: xref:framework.adoc#InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32 +:xref-InterfaceBasedRegistry-targetInterfaceId-bytes4: xref:framework.adoc#InterfaceBasedRegistry-targetInterfaceId-bytes4 +:xref-InterfaceBasedRegistry-entries-mapping-address----bool-: xref:framework.adoc#InterfaceBasedRegistry-entries-mapping-address----bool- +:xref-DAORegistry-DAORegistered-address-address-string-: xref:framework.adoc#DAORegistry-DAORegistered-address-address-string- +:xref-DAORegistry-InvalidDaoSubdomain-string-: xref:framework.adoc#DAORegistry-InvalidDaoSubdomain-string- +:xref-InterfaceBasedRegistry-ContractAlreadyRegistered-address-: xref:framework.adoc#InterfaceBasedRegistry-ContractAlreadyRegistered-address- +:xref-InterfaceBasedRegistry-ContractInterfaceInvalid-address-: xref:framework.adoc#InterfaceBasedRegistry-ContractInterfaceInvalid-address- +:xref-InterfaceBasedRegistry-ContractERC165SupportInvalid-address-: xref:framework.adoc#InterfaceBasedRegistry-ContractERC165SupportInvalid-address- +:xref-PluginRepoRegistry-constructor--: xref:framework.adoc#PluginRepoRegistry-constructor-- +:xref-PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-: xref:framework.adoc#PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar- +:xref-PluginRepoRegistry-registerPluginRepo-string-address-: xref:framework.adoc#PluginRepoRegistry-registerPluginRepo-string-address- +:xref-PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32: xref:framework.adoc#PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32 +:xref-PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar: xref:framework.adoc#PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar +:xref-InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4-: xref:framework.adoc#InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4- +:xref-InterfaceBasedRegistry-_authorizeUpgrade-address-: xref:framework.adoc#InterfaceBasedRegistry-_authorizeUpgrade-address- +:xref-InterfaceBasedRegistry-_register-address-: xref:framework.adoc#InterfaceBasedRegistry-_register-address- +:xref-InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32: xref:framework.adoc#InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32 +:xref-InterfaceBasedRegistry-targetInterfaceId-bytes4: xref:framework.adoc#InterfaceBasedRegistry-targetInterfaceId-bytes4 +:xref-InterfaceBasedRegistry-entries-mapping-address----bool-: xref:framework.adoc#InterfaceBasedRegistry-entries-mapping-address----bool- +:xref-PluginRepoRegistry-PluginRepoRegistered-string-address-: xref:framework.adoc#PluginRepoRegistry-PluginRepoRegistered-string-address- +:xref-PluginRepoRegistry-InvalidPluginSubdomain-string-: xref:framework.adoc#PluginRepoRegistry-InvalidPluginSubdomain-string- +:xref-PluginRepoRegistry-EmptyPluginRepoSubdomain--: xref:framework.adoc#PluginRepoRegistry-EmptyPluginRepoSubdomain-- +:xref-InterfaceBasedRegistry-ContractAlreadyRegistered-address-: xref:framework.adoc#InterfaceBasedRegistry-ContractAlreadyRegistered-address- +:xref-InterfaceBasedRegistry-ContractInterfaceInvalid-address-: xref:framework.adoc#InterfaceBasedRegistry-ContractInterfaceInvalid-address- +:xref-InterfaceBasedRegistry-ContractERC165SupportInvalid-address-: xref:framework.adoc#InterfaceBasedRegistry-ContractERC165SupportInvalid-address- +:xref-PluginRepo-constructor--: xref:framework.adoc#PluginRepo-constructor-- +:xref-PluginRepo-initialize-address-: xref:framework.adoc#PluginRepo-initialize-address- +:xref-PluginRepo-initializeFrom-uint8-3--bytes-: xref:framework.adoc#PluginRepo-initializeFrom-uint8-3--bytes- +:xref-PluginRepo-createVersion-uint8-address-bytes-bytes-: xref:framework.adoc#PluginRepo-createVersion-uint8-address-bytes-bytes- +:xref-PluginRepo-updateReleaseMetadata-uint8-bytes-: xref:framework.adoc#PluginRepo-updateReleaseMetadata-uint8-bytes- +:xref-PluginRepo-getLatestVersion-uint8-: xref:framework.adoc#PluginRepo-getLatestVersion-uint8- +:xref-PluginRepo-getLatestVersion-address-: xref:framework.adoc#PluginRepo-getLatestVersion-address- +:xref-PluginRepo-getVersion-struct-PluginRepo-Tag-: xref:framework.adoc#PluginRepo-getVersion-struct-PluginRepo-Tag- +:xref-PluginRepo-getVersion-bytes32-: xref:framework.adoc#PluginRepo-getVersion-bytes32- +:xref-PluginRepo-buildCount-uint8-: xref:framework.adoc#PluginRepo-buildCount-uint8- +:xref-PluginRepo-tagHash-struct-PluginRepo-Tag-: xref:framework.adoc#PluginRepo-tagHash-struct-PluginRepo-Tag- +:xref-PluginRepo-_authorizeUpgrade-address-: xref:framework.adoc#PluginRepo-_authorizeUpgrade-address- +:xref-PluginRepo-supportsInterface-bytes4-: xref:framework.adoc#PluginRepo-supportsInterface-bytes4- +:xref-PluginRepo-MAINTAINER_PERMISSION_ID-bytes32: xref:framework.adoc#PluginRepo-MAINTAINER_PERMISSION_ID-bytes32 +:xref-PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32: xref:framework.adoc#PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32 +:xref-PluginRepo-latestRelease-uint8: xref:framework.adoc#PluginRepo-latestRelease-uint8 +:xref-PermissionManager-__PermissionManager_init-address-: xref:core.adoc#PermissionManager-__PermissionManager_init-address- +:xref-PermissionManager-grant-address-address-bytes32-: xref:core.adoc#PermissionManager-grant-address-address-bytes32- +:xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition- +:xref-PermissionManager-revoke-address-address-bytes32-: xref:core.adoc#PermissionManager-revoke-address-address-bytes32- +:xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---: xref:core.adoc#PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission--- +:xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---: xref:core.adoc#PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission--- +:xref-PermissionManager-isGranted-address-address-bytes32-bytes-: xref:core.adoc#PermissionManager-isGranted-address-address-bytes32-bytes- +:xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-: xref:core.adoc#PermissionManager-_checkCondition-address-address-address-bytes32-bytes- +:xref-PermissionManager-_initializePermissionManager-address-: xref:core.adoc#PermissionManager-_initializePermissionManager-address- +:xref-PermissionManager-_grant-address-address-bytes32-: xref:core.adoc#PermissionManager-_grant-address-address-bytes32- +:xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition- +:xref-PermissionManager-_revoke-address-address-bytes32-: xref:core.adoc#PermissionManager-_revoke-address-address-bytes32- +:xref-PermissionManager-_auth-bytes32-: xref:core.adoc#PermissionManager-_auth-bytes32- +:xref-PermissionManager-permissionHash-address-address-bytes32-: xref:core.adoc#PermissionManager-permissionHash-address-address-bytes32- +:xref-PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-: xref:core.adoc#PermissionManager-isPermissionRestrictedForAnyAddr-bytes32- +:xref-PermissionManager-ROOT_PERMISSION_ID-bytes32: xref:core.adoc#PermissionManager-ROOT_PERMISSION_ID-bytes32 +:xref-PermissionManager-Granted-bytes32-address-address-address-address-: xref:core.adoc#PermissionManager-Granted-bytes32-address-address-address-address- +:xref-PermissionManager-Revoked-bytes32-address-address-address-: xref:core.adoc#PermissionManager-Revoked-bytes32-address-address-address- +:xref-IPluginRepo-VersionCreated-uint8-uint16-address-bytes-: xref:framework.adoc#IPluginRepo-VersionCreated-uint8-uint16-address-bytes- +:xref-IPluginRepo-ReleaseMetadataUpdated-uint8-bytes-: xref:framework.adoc#IPluginRepo-ReleaseMetadataUpdated-uint8-bytes- +:xref-PluginRepo-VersionHashDoesNotExist-bytes32-: xref:framework.adoc#PluginRepo-VersionHashDoesNotExist-bytes32- +:xref-PluginRepo-InvalidPluginSetupInterface--: xref:framework.adoc#PluginRepo-InvalidPluginSetupInterface-- +:xref-PluginRepo-ReleaseZeroNotAllowed--: xref:framework.adoc#PluginRepo-ReleaseZeroNotAllowed-- +:xref-PluginRepo-InvalidReleaseIncrement-uint8-uint8-: xref:framework.adoc#PluginRepo-InvalidReleaseIncrement-uint8-uint8- +:xref-PluginRepo-PluginSetupAlreadyInPreviousRelease-uint8-uint16-address-: xref:framework.adoc#PluginRepo-PluginSetupAlreadyInPreviousRelease-uint8-uint16-address- +:xref-PluginRepo-EmptyReleaseMetadata--: xref:framework.adoc#PluginRepo-EmptyReleaseMetadata-- +:xref-PluginRepo-ReleaseDoesNotExist--: xref:framework.adoc#PluginRepo-ReleaseDoesNotExist-- +:xref-PermissionManager-Unauthorized-address-address-bytes32-: xref:core.adoc#PermissionManager-Unauthorized-address-address-bytes32- +:xref-PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-: xref:core.adoc#PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address- +:xref-PermissionManager-ConditionNotAContract-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-ConditionNotAContract-contract-IPermissionCondition- +:xref-PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-: xref:core.adoc#PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition- +:xref-PermissionManager-PermissionsForAnyAddressDisallowed--: xref:core.adoc#PermissionManager-PermissionsForAnyAddressDisallowed-- +:xref-PermissionManager-AnyAddressDisallowedForWhoAndWhere--: xref:core.adoc#PermissionManager-AnyAddressDisallowedForWhoAndWhere-- +:xref-PermissionManager-GrantWithConditionNotSupported--: xref:core.adoc#PermissionManager-GrantWithConditionNotSupported-- +:xref-PluginRepo-buildsPerRelease-mapping-uint8----uint16-: xref:framework.adoc#PluginRepo-buildsPerRelease-mapping-uint8----uint16- +:xref-PluginRepo-versions-mapping-bytes32----struct-PluginRepo-Version-: xref:framework.adoc#PluginRepo-versions-mapping-bytes32----struct-PluginRepo-Version- +:xref-PluginRepo-latestTagHashForPluginSetup-mapping-address----bytes32-: xref:framework.adoc#PluginRepo-latestTagHashForPluginSetup-mapping-address----bytes32- +:xref-PermissionManager-ANY_ADDR-address: xref:core.adoc#PermissionManager-ANY_ADDR-address +:xref-PermissionManager-UNSET_FLAG-address: xref:core.adoc#PermissionManager-UNSET_FLAG-address +:xref-PermissionManager-ALLOW_FLAG-address: xref:core.adoc#PermissionManager-ALLOW_FLAG-address +:xref-PermissionManager-permissionsHashed-mapping-bytes32----address-: xref:core.adoc#PermissionManager-permissionsHashed-mapping-bytes32----address- +:xref-PluginSetupProcessor-canApply-address-bytes32-: xref:framework.adoc#PluginSetupProcessor-canApply-address-bytes32- +:xref-PluginSetupProcessor-constructor-contract-PluginRepoRegistry-: xref:framework.adoc#PluginSetupProcessor-constructor-contract-PluginRepoRegistry- +:xref-PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams-: xref:framework.adoc#PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams- +:xref-PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams-: xref:framework.adoc#PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams- +:xref-PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams-: xref:framework.adoc#PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams- +:xref-PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams-: xref:framework.adoc#PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams- +:xref-PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams-: xref:framework.adoc#PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams- +:xref-PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams-: xref:framework.adoc#PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams- +:xref-PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32-: xref:framework.adoc#PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32- +:xref-PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32: xref:framework.adoc#PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32 +:xref-PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32: xref:framework.adoc#PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32 +:xref-PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32: xref:framework.adoc#PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32 +:xref-PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState-: xref:framework.adoc#PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState- +:xref-PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry: xref:framework.adoc#PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry +:xref-PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData-: xref:framework.adoc#PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData- +:xref-PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32-: xref:framework.adoc#PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32- +:xref-PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes-: xref:framework.adoc#PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes- +:xref-PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32-: xref:framework.adoc#PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32- +:xref-PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission---: xref:framework.adoc#PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission--- +:xref-PluginSetupProcessor-UninstallationApplied-address-address-bytes32-: xref:framework.adoc#PluginSetupProcessor-UninstallationApplied-address-address-bytes32- +:xref-PluginSetupProcessor-SetupApplicationUnauthorized-address-address-bytes32-: xref:framework.adoc#PluginSetupProcessor-SetupApplicationUnauthorized-address-address-bytes32- +:xref-PluginSetupProcessor-PluginNonupgradeable-address-: xref:framework.adoc#PluginSetupProcessor-PluginNonupgradeable-address- +:xref-PluginSetupProcessor-PluginProxyUpgradeFailed-address-address-bytes-: xref:framework.adoc#PluginSetupProcessor-PluginProxyUpgradeFailed-address-address-bytes- +:xref-PluginSetupProcessor-IPluginNotSupported-address-: xref:framework.adoc#PluginSetupProcessor-IPluginNotSupported-address- +:xref-PluginSetupProcessor-PluginRepoNonexistent--: xref:framework.adoc#PluginSetupProcessor-PluginRepoNonexistent-- +:xref-PluginSetupProcessor-SetupAlreadyPrepared-bytes32-: xref:framework.adoc#PluginSetupProcessor-SetupAlreadyPrepared-bytes32- +:xref-PluginSetupProcessor-SetupNotApplicable-bytes32-: xref:framework.adoc#PluginSetupProcessor-SetupNotApplicable-bytes32- +:xref-PluginSetupProcessor-InvalidUpdateVersion-struct-PluginRepo-Tag-struct-PluginRepo-Tag-: xref:framework.adoc#PluginSetupProcessor-InvalidUpdateVersion-struct-PluginRepo-Tag-struct-PluginRepo-Tag- +:xref-PluginSetupProcessor-PluginAlreadyInstalled--: xref:framework.adoc#PluginSetupProcessor-PluginAlreadyInstalled-- +:xref-PluginSetupProcessor-InvalidAppliedSetupId-bytes32-bytes32-: xref:framework.adoc#PluginSetupProcessor-InvalidAppliedSetupId-bytes32-bytes32- +== Framework API + +=== Factories + +:daoBase: pass:normal[xref:#DAOFactory-daoBase-address[`++daoBase++`]] +:daoRegistry: pass:normal[xref:#DAOFactory-daoRegistry-contract-DAORegistry[`++daoRegistry++`]] +:pluginSetupProcessor: pass:normal[xref:#DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor[`++pluginSetupProcessor++`]] +:ROOT_PERMISSION_ID: pass:normal[xref:#DAOFactory-ROOT_PERMISSION_ID-bytes32[`++ROOT_PERMISSION_ID++`]] +:UPGRADE_DAO_PERMISSION_ID: pass:normal[xref:#DAOFactory-UPGRADE_DAO_PERMISSION_ID-bytes32[`++UPGRADE_DAO_PERMISSION_ID++`]] +:SET_TRUSTED_FORWARDER_PERMISSION_ID: pass:normal[xref:#DAOFactory-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32[`++SET_TRUSTED_FORWARDER_PERMISSION_ID++`]] +:SET_METADATA_PERMISSION_ID: pass:normal[xref:#DAOFactory-SET_METADATA_PERMISSION_ID-bytes32[`++SET_METADATA_PERMISSION_ID++`]] +:REGISTER_STANDARD_CALLBACK_PERMISSION_ID: pass:normal[xref:#DAOFactory-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32[`++REGISTER_STANDARD_CALLBACK_PERMISSION_ID++`]] +:EXECUTE_PERMISSION_ID: pass:normal[xref:#DAOFactory-EXECUTE_PERMISSION_ID-bytes32[`++EXECUTE_PERMISSION_ID++`]] +:APPLY_INSTALLATION_PERMISSION_ID: pass:normal[xref:#DAOFactory-APPLY_INSTALLATION_PERMISSION_ID-bytes32[`++APPLY_INSTALLATION_PERMISSION_ID++`]] +:DAOSettings: pass:normal[xref:#DAOFactory-DAOSettings[`++DAOSettings++`]] +:PluginSettings: pass:normal[xref:#DAOFactory-PluginSettings[`++PluginSettings++`]] +:InstalledPlugin: pass:normal[xref:#DAOFactory-InstalledPlugin[`++InstalledPlugin++`]] +:NoPluginProvided: pass:normal[xref:#DAOFactory-NoPluginProvided--[`++NoPluginProvided++`]] +:constructor: pass:normal[xref:#DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor-[`++constructor++`]] +:supportsInterface: pass:normal[xref:#DAOFactory-supportsInterface-bytes4-[`++supportsInterface++`]] +:createDao: pass:normal[xref:#DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings---[`++createDao++`]] +:_createDAO: pass:normal[xref:#DAOFactory-_createDAO-struct-DAOFactory-DAOSettings-[`++_createDAO++`]] +:_setDAOPermissions: pass:normal[xref:#DAOFactory-_setDAOPermissions-address-[`++_setDAOPermissions++`]] + +[.contract] +[[DAOFactory]] +=== `++DAOFactory++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/framework/dao/DAOFactory.sol[{github-icon},role=heading-link] + +[.contract-index] +.Functions +-- +* {xref-DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor-}[`++constructor(_registry, _pluginSetupProcessor)++`] +* {xref-DAOFactory-supportsInterface-bytes4-}[`++supportsInterface(_interfaceId)++`] +* {xref-DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings---}[`++createDao(_daoSettings, _pluginSettings)++`] +* {xref-DAOFactory-_createDAO-struct-DAOFactory-DAOSettings-}[`++_createDAO(_daoSettings)++`] +* {xref-DAOFactory-_setDAOPermissions-address-}[`++_setDAOPermissions(_daoAddress)++`] +* {xref-DAOFactory-daoBase-address}[`++daoBase()++`] +* {xref-DAOFactory-daoRegistry-contract-DAORegistry}[`++daoRegistry()++`] +* {xref-DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor}[`++pluginSetupProcessor()++`] + +[.contract-subindex-inherited] +.ProtocolVersion +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.ERC165 + +[.contract-subindex-inherited] +.IERC165 + +-- + +[.contract-index] +.Errors +-- +* {xref-DAOFactory-NoPluginProvided--}[`++NoPluginProvided()++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.ERC165 + +[.contract-subindex-inherited] +.IERC165 + +-- + +[.contract-index] +.Internal Variables +-- +* {xref-DAOFactory-ROOT_PERMISSION_ID-bytes32}[`++bytes32 ROOT_PERMISSION_ID++`] +* {xref-DAOFactory-UPGRADE_DAO_PERMISSION_ID-bytes32}[`++bytes32 UPGRADE_DAO_PERMISSION_ID++`] +* {xref-DAOFactory-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32}[`++bytes32 SET_TRUSTED_FORWARDER_PERMISSION_ID++`] +* {xref-DAOFactory-SET_METADATA_PERMISSION_ID-bytes32}[`++bytes32 SET_METADATA_PERMISSION_ID++`] +* {xref-DAOFactory-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32}[`++bytes32 REGISTER_STANDARD_CALLBACK_PERMISSION_ID++`] +* {xref-DAOFactory-EXECUTE_PERMISSION_ID-bytes32}[`++bytes32 EXECUTE_PERMISSION_ID++`] +* {xref-DAOFactory-APPLY_INSTALLATION_PERMISSION_ID-bytes32}[`++bytes32 APPLY_INSTALLATION_PERMISSION_ID++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.ERC165 + +[.contract-subindex-inherited] +.IERC165 + +-- + +[.contract-item] +[[DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor-]] +==== `[.contract-item-name]#++constructor++#++(contract DAORegistry _registry, contract PluginSetupProcessor _pluginSetupProcessor)++` [.item-kind]#public# + +The constructor setting the registry and plugin setup processor and creating the base contracts for the factory. + +[.contract-item] +[[DAOFactory-supportsInterface-bytes4-]] +==== `[.contract-item-name]#++supportsInterface++#++(bytes4 _interfaceId) → bool++` [.item-kind]#public# + +Checks if this or the parent contract supports an interface by its ID. + +[.contract-item] +[[DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings---]] +==== `[.contract-item-name]#++createDao++#++(struct DAOFactory.DAOSettings _daoSettings, struct DAOFactory.PluginSettings[] _pluginSettings) → contract DAO createdDao, struct DAOFactory.InstalledPlugin[] installedPlugins++` [.item-kind]#external# + +Creates a new DAO, registers it in the DAO registry, and optionally installs plugins via the plugin setup processor. + +If `_pluginSettings` is empty, the caller is granted `EXECUTE_PERMISSION` on the DAO. + +[.contract-item] +[[DAOFactory-_createDAO-struct-DAOFactory-DAOSettings-]] +==== `[.contract-item-name]#++_createDAO++#++(struct DAOFactory.DAOSettings _daoSettings) → contract DAO dao++` [.item-kind]#internal# + +Deploys a new DAO `ERC1967` proxy, and initialize it with this contract as the initial owner. + +[.contract-item] +[[DAOFactory-_setDAOPermissions-address-]] +==== `[.contract-item-name]#++_setDAOPermissions++#++(address _daoAddress)++` [.item-kind]#internal# + +Sets the required permissions for the new DAO. + +[.contract-item] +[[DAOFactory-daoBase-address]] +==== `[.contract-item-name]#++daoBase++#++() → address++` [.item-kind]#public# + +The DAO base contract, to be used for creating new `DAO`s via `createERC1967Proxy` function. + +[.contract-item] +[[DAOFactory-daoRegistry-contract-DAORegistry]] +==== `[.contract-item-name]#++daoRegistry++#++() → contract DAORegistry++` [.item-kind]#public# + +The DAO registry listing the `DAO` contracts created via this contract. + +[.contract-item] +[[DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor]] +==== `[.contract-item-name]#++pluginSetupProcessor++#++() → contract PluginSetupProcessor++` [.item-kind]#public# + +The plugin setup processor for installing plugins on the newly created `DAO`s. + +[.contract-item] +[[DAOFactory-NoPluginProvided--]] +==== `[.contract-item-name]#++NoPluginProvided++#++()++` [.item-kind]#error# + +Thrown if `PluginSettings` array is empty, and no plugin is provided. + +[.contract-item] +[[DAOFactory-ROOT_PERMISSION_ID-bytes32]] +==== `bytes32 [.contract-item-name]#++ROOT_PERMISSION_ID++#` [.item-kind]#internal# + +[.contract-item] +[[DAOFactory-UPGRADE_DAO_PERMISSION_ID-bytes32]] +==== `bytes32 [.contract-item-name]#++UPGRADE_DAO_PERMISSION_ID++#` [.item-kind]#internal# + +[.contract-item] +[[DAOFactory-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32]] +==== `bytes32 [.contract-item-name]#++SET_TRUSTED_FORWARDER_PERMISSION_ID++#` [.item-kind]#internal# + +[.contract-item] +[[DAOFactory-SET_METADATA_PERMISSION_ID-bytes32]] +==== `bytes32 [.contract-item-name]#++SET_METADATA_PERMISSION_ID++#` [.item-kind]#internal# + +[.contract-item] +[[DAOFactory-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32]] +==== `bytes32 [.contract-item-name]#++REGISTER_STANDARD_CALLBACK_PERMISSION_ID++#` [.item-kind]#internal# + +[.contract-item] +[[DAOFactory-EXECUTE_PERMISSION_ID-bytes32]] +==== `bytes32 [.contract-item-name]#++EXECUTE_PERMISSION_ID++#` [.item-kind]#internal# + +[.contract-item] +[[DAOFactory-APPLY_INSTALLATION_PERMISSION_ID-bytes32]] +==== `bytes32 [.contract-item-name]#++APPLY_INSTALLATION_PERMISSION_ID++#` [.item-kind]#internal# + +:pluginRepoRegistry: pass:normal[xref:#PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry[`++pluginRepoRegistry++`]] +:pluginRepoBase: pass:normal[xref:#PluginRepoFactory-pluginRepoBase-address[`++pluginRepoBase++`]] +:constructor: pass:normal[xref:#PluginRepoFactory-constructor-contract-PluginRepoRegistry-[`++constructor++`]] +:supportsInterface: pass:normal[xref:#PluginRepoFactory-supportsInterface-bytes4-[`++supportsInterface++`]] +:createPluginRepo: pass:normal[xref:#PluginRepoFactory-createPluginRepo-string-address-[`++createPluginRepo++`]] +:createPluginRepoWithFirstVersion: pass:normal[xref:#PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes-[`++createPluginRepoWithFirstVersion++`]] +:_setPluginRepoPermissions: pass:normal[xref:#PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address-[`++_setPluginRepoPermissions++`]] +:_createPluginRepo: pass:normal[xref:#PluginRepoFactory-_createPluginRepo-string-address-[`++_createPluginRepo++`]] + +[.contract] +[[PluginRepoFactory]] +=== `++PluginRepoFactory++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/framework/plugin/repo/PluginRepoFactory.sol[{github-icon},role=heading-link] + +[.contract-index] +.Functions +-- +* {xref-PluginRepoFactory-constructor-contract-PluginRepoRegistry-}[`++constructor(_pluginRepoRegistry)++`] +* {xref-PluginRepoFactory-supportsInterface-bytes4-}[`++supportsInterface(_interfaceId)++`] +* {xref-PluginRepoFactory-createPluginRepo-string-address-}[`++createPluginRepo(_subdomain, _initialOwner)++`] +* {xref-PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes-}[`++createPluginRepoWithFirstVersion(_subdomain, _pluginSetup, _maintainer, _releaseMetadata, _buildMetadata)++`] +* {xref-PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address-}[`++_setPluginRepoPermissions(pluginRepo, maintainer)++`] +* {xref-PluginRepoFactory-_createPluginRepo-string-address-}[`++_createPluginRepo(_subdomain, _initialOwner)++`] +* {xref-PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry}[`++pluginRepoRegistry()++`] +* {xref-PluginRepoFactory-pluginRepoBase-address}[`++pluginRepoBase()++`] + +[.contract-subindex-inherited] +.ProtocolVersion +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.ERC165 + +[.contract-subindex-inherited] +.IERC165 + +-- + +[.contract-item] +[[PluginRepoFactory-constructor-contract-PluginRepoRegistry-]] +==== `[.contract-item-name]#++constructor++#++(contract PluginRepoRegistry _pluginRepoRegistry)++` [.item-kind]#public# + +Initializes the addresses of the Aragon plugin registry and `PluginRepo` base contract to proxy to. + +[.contract-item] +[[PluginRepoFactory-supportsInterface-bytes4-]] +==== `[.contract-item-name]#++supportsInterface++#++(bytes4 _interfaceId) → bool++` [.item-kind]#public# + +Checks if this or the parent contract supports an interface by its ID. + +[.contract-item] +[[PluginRepoFactory-createPluginRepo-string-address-]] +==== `[.contract-item-name]#++createPluginRepo++#++(string _subdomain, address _initialOwner) → contract PluginRepo++` [.item-kind]#external# + +Creates a plugin repository proxy pointing to the `pluginRepoBase` implementation and registers it in the Aragon plugin registry. + +[.contract-item] +[[PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes-]] +==== `[.contract-item-name]#++createPluginRepoWithFirstVersion++#++(string _subdomain, address _pluginSetup, address _maintainer, bytes _releaseMetadata, bytes _buildMetadata) → contract PluginRepo pluginRepo++` [.item-kind]#external# + +Creates and registers a `PluginRepo` with an ENS subdomain and publishes an initial version `1.1`. + +After the creation of the `PluginRepo` and release of the first version by the factory, ownership is transferred to the `_maintainer` address. + +[.contract-item] +[[PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address-]] +==== `[.contract-item-name]#++_setPluginRepoPermissions++#++(contract PluginRepo pluginRepo, address maintainer)++` [.item-kind]#internal# + +Set the final permissions for the published plugin repository maintainer. All permissions are revoked from the plugin factory and granted to the specified plugin maintainer. + +The plugin maintainer is granted the `MAINTAINER_PERMISSION_ID`, `UPGRADE_REPO_PERMISSION_ID`, and `ROOT_PERMISSION_ID`. + +[.contract-item] +[[PluginRepoFactory-_createPluginRepo-string-address-]] +==== `[.contract-item-name]#++_createPluginRepo++#++(string _subdomain, address _initialOwner) → contract PluginRepo pluginRepo++` [.item-kind]#internal# + +Internal method creating a `PluginRepo` via the [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) proxy pattern from the provided base contract and registering it in the Aragon plugin registry. + +Passing an empty `_subdomain` will cause the transaction to revert. + +[.contract-item] +[[PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry]] +==== `[.contract-item-name]#++pluginRepoRegistry++#++() → contract PluginRepoRegistry++` [.item-kind]#public# + +The Aragon plugin registry contract. + +[.contract-item] +[[PluginRepoFactory-pluginRepoBase-address]] +==== `[.contract-item-name]#++pluginRepoBase++#++() → address++` [.item-kind]#public# + +The address of the `PluginRepo` base contract to proxy to.. + +=== Registries + +:REGISTER_DAO_PERMISSION_ID: pass:normal[xref:#DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32[`++REGISTER_DAO_PERMISSION_ID++`]] +:subdomainRegistrar: pass:normal[xref:#DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar[`++subdomainRegistrar++`]] +:InvalidDaoSubdomain: pass:normal[xref:#DAORegistry-InvalidDaoSubdomain-string-[`++InvalidDaoSubdomain++`]] +:DAORegistered: pass:normal[xref:#DAORegistry-DAORegistered-address-address-string-[`++DAORegistered++`]] +:constructor: pass:normal[xref:#DAORegistry-constructor--[`++constructor++`]] +:initialize: pass:normal[xref:#DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-[`++initialize++`]] +:register: pass:normal[xref:#DAORegistry-register-contract-IDAO-address-string-[`++register++`]] + +[.contract] +[[DAORegistry]] +=== `++DAORegistry++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/framework/dao/DAORegistry.sol[{github-icon},role=heading-link] + +[.contract-index] +.Functions +-- +* {xref-DAORegistry-constructor--}[`++constructor()++`] +* {xref-DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-}[`++initialize(_managingDao, _subdomainRegistrar)++`] +* {xref-DAORegistry-register-contract-IDAO-address-string-}[`++register(dao, creator, subdomain)++`] +* {xref-DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32}[`++REGISTER_DAO_PERMISSION_ID()++`] +* {xref-DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar}[`++subdomainRegistrar()++`] + +[.contract-subindex-inherited] +.ProtocolVersion +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.InterfaceBasedRegistry +* {xref-InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4-}[`++__InterfaceBasedRegistry_init(_managingDao, _targetInterfaceId)++`] +* {xref-InterfaceBasedRegistry-_authorizeUpgrade-address-}[`++_authorizeUpgrade()++`] +* {xref-InterfaceBasedRegistry-_register-address-}[`++_register(_registrant)++`] +* {xref-InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32}[`++UPGRADE_REGISTRY_PERMISSION_ID()++`] +* {xref-InterfaceBasedRegistry-targetInterfaceId-bytes4}[`++targetInterfaceId()++`] +* {xref-InterfaceBasedRegistry-entries-mapping-address----bool-}[`++entries()++`] + +[.contract-subindex-inherited] +.DaoAuthorizableUpgradeable +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol[__DaoAuthorizableUpgradeable_init] +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol[dao] + +[.contract-subindex-inherited] +.ContextUpgradeable + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Events +-- +* {xref-DAORegistry-DAORegistered-address-address-string-}[`++DAORegistered(dao, creator, subdomain)++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.InterfaceBasedRegistry + +[.contract-subindex-inherited] +.DaoAuthorizableUpgradeable + +[.contract-subindex-inherited] +.ContextUpgradeable + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Errors +-- +* {xref-DAORegistry-InvalidDaoSubdomain-string-}[`++InvalidDaoSubdomain(subdomain)++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.InterfaceBasedRegistry +* {xref-InterfaceBasedRegistry-ContractAlreadyRegistered-address-}[`++ContractAlreadyRegistered(registrant)++`] +* {xref-InterfaceBasedRegistry-ContractInterfaceInvalid-address-}[`++ContractInterfaceInvalid(registrant)++`] +* {xref-InterfaceBasedRegistry-ContractERC165SupportInvalid-address-}[`++ContractERC165SupportInvalid(registrant)++`] + +[.contract-subindex-inherited] +.DaoAuthorizableUpgradeable + +[.contract-subindex-inherited] +.ContextUpgradeable + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-item] +[[DAORegistry-constructor--]] +==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#public# + +Used to disallow initializing the implementation contract by an attacker for extra safety. + +[.contract-item] +[[DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-]] +==== `[.contract-item-name]#++initialize++#++(contract IDAO _managingDao, contract ENSSubdomainRegistrar _subdomainRegistrar)++` [.item-kind]#external# + +Initializes the contract. + +[.contract-item] +[[DAORegistry-register-contract-IDAO-address-string-]] +==== `[.contract-item-name]#++register++#++(contract IDAO dao, address creator, string subdomain)++` [.item-kind]#external# + +Registers a DAO by its address. If a non-empty subdomain name is provided that is not taken already, the DAO becomes the owner of the ENS name. + +A subdomain is unique within the Aragon DAO framework and can get stored here. + +[.contract-item] +[[DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++REGISTER_DAO_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `register` function. + +[.contract-item] +[[DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar]] +==== `[.contract-item-name]#++subdomainRegistrar++#++() → contract ENSSubdomainRegistrar++` [.item-kind]#public# + +The ENS subdomain registrar registering the DAO subdomains. + +[.contract-item] +[[DAORegistry-DAORegistered-address-address-string-]] +==== `[.contract-item-name]#++DAORegistered++#++(address indexed dao, address indexed creator, string subdomain)++` [.item-kind]#event# + +Emitted when a new DAO is registered. + +[.contract-item] +[[DAORegistry-InvalidDaoSubdomain-string-]] +==== `[.contract-item-name]#++InvalidDaoSubdomain++#++(string subdomain)++` [.item-kind]#error# + +Thrown if the DAO subdomain doesn't match the regex `[0-9a-z\-]` + +:REGISTER_PLUGIN_REPO_PERMISSION_ID: pass:normal[xref:#PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32[`++REGISTER_PLUGIN_REPO_PERMISSION_ID++`]] +:subdomainRegistrar: pass:normal[xref:#PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar[`++subdomainRegistrar++`]] +:PluginRepoRegistered: pass:normal[xref:#PluginRepoRegistry-PluginRepoRegistered-string-address-[`++PluginRepoRegistered++`]] +:InvalidPluginSubdomain: pass:normal[xref:#PluginRepoRegistry-InvalidPluginSubdomain-string-[`++InvalidPluginSubdomain++`]] +:EmptyPluginRepoSubdomain: pass:normal[xref:#PluginRepoRegistry-EmptyPluginRepoSubdomain--[`++EmptyPluginRepoSubdomain++`]] +:constructor: pass:normal[xref:#PluginRepoRegistry-constructor--[`++constructor++`]] +:initialize: pass:normal[xref:#PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-[`++initialize++`]] +:registerPluginRepo: pass:normal[xref:#PluginRepoRegistry-registerPluginRepo-string-address-[`++registerPluginRepo++`]] + +[.contract] +[[PluginRepoRegistry]] +=== `++PluginRepoRegistry++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/framework/plugin/repo/PluginRepoRegistry.sol[{github-icon},role=heading-link] + +[.contract-index] +.Functions +-- +* {xref-PluginRepoRegistry-constructor--}[`++constructor()++`] +* {xref-PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-}[`++initialize(_dao, _subdomainRegistrar)++`] +* {xref-PluginRepoRegistry-registerPluginRepo-string-address-}[`++registerPluginRepo(subdomain, pluginRepo)++`] +* {xref-PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32}[`++REGISTER_PLUGIN_REPO_PERMISSION_ID()++`] +* {xref-PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar}[`++subdomainRegistrar()++`] + +[.contract-subindex-inherited] +.ProtocolVersion +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.InterfaceBasedRegistry +* {xref-InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4-}[`++__InterfaceBasedRegistry_init(_managingDao, _targetInterfaceId)++`] +* {xref-InterfaceBasedRegistry-_authorizeUpgrade-address-}[`++_authorizeUpgrade()++`] +* {xref-InterfaceBasedRegistry-_register-address-}[`++_register(_registrant)++`] +* {xref-InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32}[`++UPGRADE_REGISTRY_PERMISSION_ID()++`] +* {xref-InterfaceBasedRegistry-targetInterfaceId-bytes4}[`++targetInterfaceId()++`] +* {xref-InterfaceBasedRegistry-entries-mapping-address----bool-}[`++entries()++`] + +[.contract-subindex-inherited] +.DaoAuthorizableUpgradeable +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol[__DaoAuthorizableUpgradeable_init] +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol[dao] + +[.contract-subindex-inherited] +.ContextUpgradeable + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Events +-- +* {xref-PluginRepoRegistry-PluginRepoRegistered-string-address-}[`++PluginRepoRegistered(subdomain, pluginRepo)++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.InterfaceBasedRegistry + +[.contract-subindex-inherited] +.DaoAuthorizableUpgradeable + +[.contract-subindex-inherited] +.ContextUpgradeable + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Errors +-- +* {xref-PluginRepoRegistry-InvalidPluginSubdomain-string-}[`++InvalidPluginSubdomain(subdomain)++`] +* {xref-PluginRepoRegistry-EmptyPluginRepoSubdomain--}[`++EmptyPluginRepoSubdomain()++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.InterfaceBasedRegistry +* {xref-InterfaceBasedRegistry-ContractAlreadyRegistered-address-}[`++ContractAlreadyRegistered(registrant)++`] +* {xref-InterfaceBasedRegistry-ContractInterfaceInvalid-address-}[`++ContractInterfaceInvalid(registrant)++`] +* {xref-InterfaceBasedRegistry-ContractERC165SupportInvalid-address-}[`++ContractERC165SupportInvalid(registrant)++`] + +[.contract-subindex-inherited] +.DaoAuthorizableUpgradeable + +[.contract-subindex-inherited] +.ContextUpgradeable + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-item] +[[PluginRepoRegistry-constructor--]] +==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#public# + +Used to disallow initializing the implementation contract by an attacker for extra safety. + +[.contract-item] +[[PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-]] +==== `[.contract-item-name]#++initialize++#++(contract IDAO _dao, contract ENSSubdomainRegistrar _subdomainRegistrar)++` [.item-kind]#external# + +Initializes the contract by setting calling the `InterfaceBasedRegistry` base class initialize method. + +[.contract-item] +[[PluginRepoRegistry-registerPluginRepo-string-address-]] +==== `[.contract-item-name]#++registerPluginRepo++#++(string subdomain, address pluginRepo)++` [.item-kind]#external# + +Registers a plugin repository with a subdomain and address. + +[.contract-item] +[[PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++REGISTER_PLUGIN_REPO_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `register` function. + +[.contract-item] +[[PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar]] +==== `[.contract-item-name]#++subdomainRegistrar++#++() → contract ENSSubdomainRegistrar++` [.item-kind]#public# + +The ENS subdomain registrar registering the PluginRepo subdomains. + +[.contract-item] +[[PluginRepoRegistry-PluginRepoRegistered-string-address-]] +==== `[.contract-item-name]#++PluginRepoRegistered++#++(string subdomain, address pluginRepo)++` [.item-kind]#event# + +Emitted if a new plugin repository is registered. + +[.contract-item] +[[PluginRepoRegistry-InvalidPluginSubdomain-string-]] +==== `[.contract-item-name]#++InvalidPluginSubdomain++#++(string subdomain)++` [.item-kind]#error# + +Thrown if the plugin subdomain doesn't match the regex `[0-9a-z\-]` + +[.contract-item] +[[PluginRepoRegistry-EmptyPluginRepoSubdomain--]] +==== `[.contract-item-name]#++EmptyPluginRepoSubdomain++#++()++` [.item-kind]#error# + +Thrown if the plugin repository subdomain is empty. + +=== Framework + +:Tag: pass:normal[xref:#PluginRepo-Tag[`++Tag++`]] +:Version: pass:normal[xref:#PluginRepo-Version[`++Version++`]] +:MAINTAINER_PERMISSION_ID: pass:normal[xref:#PluginRepo-MAINTAINER_PERMISSION_ID-bytes32[`++MAINTAINER_PERMISSION_ID++`]] +:UPGRADE_REPO_PERMISSION_ID: pass:normal[xref:#PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32[`++UPGRADE_REPO_PERMISSION_ID++`]] +:buildsPerRelease: pass:normal[xref:#PluginRepo-buildsPerRelease-mapping-uint8----uint16-[`++buildsPerRelease++`]] +:versions: pass:normal[xref:#PluginRepo-versions-mapping-bytes32----struct-PluginRepo-Version-[`++versions++`]] +:latestTagHashForPluginSetup: pass:normal[xref:#PluginRepo-latestTagHashForPluginSetup-mapping-address----bytes32-[`++latestTagHashForPluginSetup++`]] +:latestRelease: pass:normal[xref:#PluginRepo-latestRelease-uint8[`++latestRelease++`]] +:VersionHashDoesNotExist: pass:normal[xref:#PluginRepo-VersionHashDoesNotExist-bytes32-[`++VersionHashDoesNotExist++`]] +:InvalidPluginSetupInterface: pass:normal[xref:#PluginRepo-InvalidPluginSetupInterface--[`++InvalidPluginSetupInterface++`]] +:ReleaseZeroNotAllowed: pass:normal[xref:#PluginRepo-ReleaseZeroNotAllowed--[`++ReleaseZeroNotAllowed++`]] +:InvalidReleaseIncrement: pass:normal[xref:#PluginRepo-InvalidReleaseIncrement-uint8-uint8-[`++InvalidReleaseIncrement++`]] +:PluginSetupAlreadyInPreviousRelease: pass:normal[xref:#PluginRepo-PluginSetupAlreadyInPreviousRelease-uint8-uint16-address-[`++PluginSetupAlreadyInPreviousRelease++`]] +:EmptyReleaseMetadata: pass:normal[xref:#PluginRepo-EmptyReleaseMetadata--[`++EmptyReleaseMetadata++`]] +:ReleaseDoesNotExist: pass:normal[xref:#PluginRepo-ReleaseDoesNotExist--[`++ReleaseDoesNotExist++`]] +:constructor: pass:normal[xref:#PluginRepo-constructor--[`++constructor++`]] +:initialize: pass:normal[xref:#PluginRepo-initialize-address-[`++initialize++`]] +:initializeFrom: pass:normal[xref:#PluginRepo-initializeFrom-uint8-3--bytes-[`++initializeFrom++`]] +:createVersion: pass:normal[xref:#PluginRepo-createVersion-uint8-address-bytes-bytes-[`++createVersion++`]] +:updateReleaseMetadata: pass:normal[xref:#PluginRepo-updateReleaseMetadata-uint8-bytes-[`++updateReleaseMetadata++`]] +:getLatestVersion: pass:normal[xref:#PluginRepo-getLatestVersion-uint8-[`++getLatestVersion++`]] +:getLatestVersion: pass:normal[xref:#PluginRepo-getLatestVersion-address-[`++getLatestVersion++`]] +:getVersion: pass:normal[xref:#PluginRepo-getVersion-struct-PluginRepo-Tag-[`++getVersion++`]] +:getVersion: pass:normal[xref:#PluginRepo-getVersion-bytes32-[`++getVersion++`]] +:buildCount: pass:normal[xref:#PluginRepo-buildCount-uint8-[`++buildCount++`]] +:tagHash: pass:normal[xref:#PluginRepo-tagHash-struct-PluginRepo-Tag-[`++tagHash++`]] +:_authorizeUpgrade: pass:normal[xref:#PluginRepo-_authorizeUpgrade-address-[`++_authorizeUpgrade++`]] +:supportsInterface: pass:normal[xref:#PluginRepo-supportsInterface-bytes4-[`++supportsInterface++`]] + +[.contract] +[[PluginRepo]] +=== `++PluginRepo++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/framework/plugin/repo/PluginRepo.sol[{github-icon},role=heading-link] + +[.contract-index] +.Functions +-- +* {xref-PluginRepo-constructor--}[`++constructor()++`] +* {xref-PluginRepo-initialize-address-}[`++initialize(initialOwner)++`] +* {xref-PluginRepo-initializeFrom-uint8-3--bytes-}[`++initializeFrom(_previousProtocolVersion, _initData)++`] +* {xref-PluginRepo-createVersion-uint8-address-bytes-bytes-}[`++createVersion(_release, _pluginSetup, _buildMetadata, _releaseMetadata)++`] +* {xref-PluginRepo-updateReleaseMetadata-uint8-bytes-}[`++updateReleaseMetadata(_release, _releaseMetadata)++`] +* {xref-PluginRepo-getLatestVersion-uint8-}[`++getLatestVersion(_release)++`] +* {xref-PluginRepo-getLatestVersion-address-}[`++getLatestVersion(_pluginSetup)++`] +* {xref-PluginRepo-getVersion-struct-PluginRepo-Tag-}[`++getVersion(_tag)++`] +* {xref-PluginRepo-getVersion-bytes32-}[`++getVersion(_tagHash)++`] +* {xref-PluginRepo-buildCount-uint8-}[`++buildCount(_release)++`] +* {xref-PluginRepo-tagHash-struct-PluginRepo-Tag-}[`++tagHash(_tag)++`] +* {xref-PluginRepo-_authorizeUpgrade-address-}[`++_authorizeUpgrade()++`] +* {xref-PluginRepo-supportsInterface-bytes4-}[`++supportsInterface(_interfaceId)++`] +* {xref-PluginRepo-MAINTAINER_PERMISSION_ID-bytes32}[`++MAINTAINER_PERMISSION_ID()++`] +* {xref-PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32}[`++UPGRADE_REPO_PERMISSION_ID()++`] +* {xref-PluginRepo-latestRelease-uint8}[`++latestRelease()++`] + +[.contract-subindex-inherited] +.PermissionManager +* {xref-PermissionManager-__PermissionManager_init-address-}[`++__PermissionManager_init(_initialOwner)++`] +* {xref-PermissionManager-grant-address-address-bytes32-}[`++grant(_where, _who, _permissionId)++`] +* {xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++grantWithCondition(_where, _who, _permissionId, _condition)++`] +* {xref-PermissionManager-revoke-address-address-bytes32-}[`++revoke(_where, _who, _permissionId)++`] +* {xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---}[`++applySingleTargetPermissions(_where, items)++`] +* {xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---}[`++applyMultiTargetPermissions(_items)++`] +* {xref-PermissionManager-isGranted-address-address-bytes32-bytes-}[`++isGranted(_where, _who, _permissionId, _data)++`] +* {xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-}[`++_checkCondition(_condition, _where, _who, _permissionId, _data)++`] +* {xref-PermissionManager-_initializePermissionManager-address-}[`++_initializePermissionManager(_initialOwner)++`] +* {xref-PermissionManager-_grant-address-address-bytes32-}[`++_grant(_where, _who, _permissionId)++`] +* {xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++_grantWithCondition(_where, _who, _permissionId, _condition)++`] +* {xref-PermissionManager-_revoke-address-address-bytes32-}[`++_revoke(_where, _who, _permissionId)++`] +* {xref-PermissionManager-_auth-bytes32-}[`++_auth(_permissionId)++`] +* {xref-PermissionManager-permissionHash-address-address-bytes32-}[`++permissionHash(_where, _who, _permissionId)++`] +* {xref-PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-}[`++isPermissionRestrictedForAnyAddr(_permissionId)++`] +* {xref-PermissionManager-ROOT_PERMISSION_ID-bytes32}[`++ROOT_PERMISSION_ID()++`] + +[.contract-subindex-inherited] +.ProtocolVersion +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.IPluginRepo + +[.contract-subindex-inherited] +.ERC165Upgradeable + +[.contract-subindex-inherited] +.IERC165Upgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Events +-- + +[.contract-subindex-inherited] +.PermissionManager +* {xref-PermissionManager-Granted-bytes32-address-address-address-address-}[`++Granted(permissionId, here, where, who, condition)++`] +* {xref-PermissionManager-Revoked-bytes32-address-address-address-}[`++Revoked(permissionId, here, where, who)++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.IPluginRepo +* {xref-IPluginRepo-VersionCreated-uint8-uint16-address-bytes-}[`++VersionCreated(release, build, pluginSetup, buildMetadata)++`] +* {xref-IPluginRepo-ReleaseMetadataUpdated-uint8-bytes-}[`++ReleaseMetadataUpdated(release, releaseMetadata)++`] + +[.contract-subindex-inherited] +.ERC165Upgradeable + +[.contract-subindex-inherited] +.IERC165Upgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Errors +-- +* {xref-PluginRepo-VersionHashDoesNotExist-bytes32-}[`++VersionHashDoesNotExist(versionHash)++`] +* {xref-PluginRepo-InvalidPluginSetupInterface--}[`++InvalidPluginSetupInterface()++`] +* {xref-PluginRepo-ReleaseZeroNotAllowed--}[`++ReleaseZeroNotAllowed()++`] +* {xref-PluginRepo-InvalidReleaseIncrement-uint8-uint8-}[`++InvalidReleaseIncrement(latestRelease, newRelease)++`] +* {xref-PluginRepo-PluginSetupAlreadyInPreviousRelease-uint8-uint16-address-}[`++PluginSetupAlreadyInPreviousRelease(release, build, pluginSetup)++`] +* {xref-PluginRepo-EmptyReleaseMetadata--}[`++EmptyReleaseMetadata()++`] +* {xref-PluginRepo-ReleaseDoesNotExist--}[`++ReleaseDoesNotExist()++`] + +[.contract-subindex-inherited] +.PermissionManager +* {xref-PermissionManager-Unauthorized-address-address-bytes32-}[`++Unauthorized(where, who, permissionId)++`] +* {xref-PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-}[`++PermissionAlreadyGrantedForDifferentCondition(where, who, permissionId, currentCondition, newCondition)++`] +* {xref-PermissionManager-ConditionNotAContract-contract-IPermissionCondition-}[`++ConditionNotAContract(condition)++`] +* {xref-PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-}[`++ConditionInterfaceNotSupported(condition)++`] +* {xref-PermissionManager-PermissionsForAnyAddressDisallowed--}[`++PermissionsForAnyAddressDisallowed()++`] +* {xref-PermissionManager-AnyAddressDisallowedForWhoAndWhere--}[`++AnyAddressDisallowedForWhoAndWhere()++`] +* {xref-PermissionManager-GrantWithConditionNotSupported--}[`++GrantWithConditionNotSupported()++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.IPluginRepo + +[.contract-subindex-inherited] +.ERC165Upgradeable + +[.contract-subindex-inherited] +.IERC165Upgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-index] +.Internal Variables +-- +* {xref-PluginRepo-buildsPerRelease-mapping-uint8----uint16-}[`++mapping(uint8 => uint16) buildsPerRelease++`] +* {xref-PluginRepo-versions-mapping-bytes32----struct-PluginRepo-Version-}[`++mapping(bytes32 => struct PluginRepo.Version) versions++`] +* {xref-PluginRepo-latestTagHashForPluginSetup-mapping-address----bytes32-}[`++mapping(address => bytes32) latestTagHashForPluginSetup++`] + +[.contract-subindex-inherited] +.PermissionManager +* {xref-PermissionManager-ANY_ADDR-address}[`++address constant ANY_ADDR++`] +* {xref-PermissionManager-UNSET_FLAG-address}[`++address constant UNSET_FLAG++`] +* {xref-PermissionManager-ALLOW_FLAG-address}[`++address constant ALLOW_FLAG++`] +* {xref-PermissionManager-permissionsHashed-mapping-bytes32----address-}[`++mapping(bytes32 => address) permissionsHashed++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +[.contract-subindex-inherited] +.UUPSUpgradeable + +[.contract-subindex-inherited] +.ERC1967UpgradeUpgradeable + +[.contract-subindex-inherited] +.IERC1967Upgradeable + +[.contract-subindex-inherited] +.IERC1822ProxiableUpgradeable + +[.contract-subindex-inherited] +.IPluginRepo + +[.contract-subindex-inherited] +.ERC165Upgradeable + +[.contract-subindex-inherited] +.IERC165Upgradeable + +[.contract-subindex-inherited] +.Initializable + +-- + +[.contract-item] +[[PluginRepo-constructor--]] +==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#public# + +Used to disallow initializing the implementation contract by an attacker for extra safety. + +[.contract-item] +[[PluginRepo-initialize-address-]] +==== `[.contract-item-name]#++initialize++#++(address initialOwner)++` [.item-kind]#external# + +Initializes the contract by +- initializing the permission manager +- granting the `MAINTAINER_PERMISSION_ID` permission to the initial owner. + +This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). + +[.contract-item] +[[PluginRepo-initializeFrom-uint8-3--bytes-]] +==== `[.contract-item-name]#++initializeFrom++#++(uint8[3] _previousProtocolVersion, bytes _initData)++` [.item-kind]#external# + +Initializes the pluginRepo after an upgrade from a previous protocol version. + +This function is a placeholder until we require reinitialization. + +[.contract-item] +[[PluginRepo-createVersion-uint8-address-bytes-bytes-]] +==== `[.contract-item-name]#++createVersion++#++(uint8 _release, address _pluginSetup, bytes _buildMetadata, bytes _releaseMetadata)++` [.item-kind]#external# + +Creates a new plugin version as the latest build for an existing release number or the first build for a new release number for the provided `PluginSetup` contract address and metadata. + +[.contract-item] +[[PluginRepo-updateReleaseMetadata-uint8-bytes-]] +==== `[.contract-item-name]#++updateReleaseMetadata++#++(uint8 _release, bytes _releaseMetadata)++` [.item-kind]#external# + +Updates the metadata for release with content `@fromHex(_releaseMetadata)`. + +[.contract-item] +[[PluginRepo-getLatestVersion-uint8-]] +==== `[.contract-item-name]#++getLatestVersion++#++(uint8 _release) → struct PluginRepo.Version++` [.item-kind]#public# + +Returns the latest version for a given release number. + +[.contract-item] +[[PluginRepo-getLatestVersion-address-]] +==== `[.contract-item-name]#++getLatestVersion++#++(address _pluginSetup) → struct PluginRepo.Version++` [.item-kind]#public# + +Returns the latest version for a given plugin setup. + +[.contract-item] +[[PluginRepo-getVersion-struct-PluginRepo-Tag-]] +==== `[.contract-item-name]#++getVersion++#++(struct PluginRepo.Tag _tag) → struct PluginRepo.Version++` [.item-kind]#public# + +Returns the version associated with a tag. + +[.contract-item] +[[PluginRepo-getVersion-bytes32-]] +==== `[.contract-item-name]#++getVersion++#++(bytes32 _tagHash) → struct PluginRepo.Version++` [.item-kind]#public# + +Returns the version for a tag hash. + +[.contract-item] +[[PluginRepo-buildCount-uint8-]] +==== `[.contract-item-name]#++buildCount++#++(uint8 _release) → uint256++` [.item-kind]#public# + +Gets the total number of builds for a given release number. + +[.contract-item] +[[PluginRepo-tagHash-struct-PluginRepo-Tag-]] +==== `[.contract-item-name]#++tagHash++#++(struct PluginRepo.Tag _tag) → bytes32++` [.item-kind]#internal# + +The hash of the version tag obtained from the packed, bytes-encoded release and build number. + +[.contract-item] +[[PluginRepo-_authorizeUpgrade-address-]] +==== `[.contract-item-name]#++_authorizeUpgrade++#++(address)++` [.item-kind]#internal# + +Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). + +The caller must have the `UPGRADE_REPO_PERMISSION_ID` permission. + +[.contract-item] +[[PluginRepo-supportsInterface-bytes4-]] +==== `[.contract-item-name]#++supportsInterface++#++(bytes4 _interfaceId) → bool++` [.item-kind]#public# + +Checks if this or the parent contract supports an interface by its ID. + +[.contract-item] +[[PluginRepo-MAINTAINER_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++MAINTAINER_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `createVersion` function. + +[.contract-item] +[[PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++UPGRADE_REPO_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `createVersion` function. + +[.contract-item] +[[PluginRepo-latestRelease-uint8]] +==== `[.contract-item-name]#++latestRelease++#++() → uint8++` [.item-kind]#public# + +The ID of the latest release. + +The maximum release number is 255. + +[.contract-item] +[[PluginRepo-VersionHashDoesNotExist-bytes32-]] +==== `[.contract-item-name]#++VersionHashDoesNotExist++#++(bytes32 versionHash)++` [.item-kind]#error# + +Thrown if a version does not exist. + +[.contract-item] +[[PluginRepo-InvalidPluginSetupInterface--]] +==== `[.contract-item-name]#++InvalidPluginSetupInterface++#++()++` [.item-kind]#error# + +Thrown if a plugin setup contract does not inherit from `PluginSetup`. + +[.contract-item] +[[PluginRepo-ReleaseZeroNotAllowed--]] +==== `[.contract-item-name]#++ReleaseZeroNotAllowed++#++()++` [.item-kind]#error# + +Thrown if a release number is zero. + +[.contract-item] +[[PluginRepo-InvalidReleaseIncrement-uint8-uint8-]] +==== `[.contract-item-name]#++InvalidReleaseIncrement++#++(uint8 latestRelease, uint8 newRelease)++` [.item-kind]#error# + +Thrown if a release number is incremented by more than one. + +[.contract-item] +[[PluginRepo-PluginSetupAlreadyInPreviousRelease-uint8-uint16-address-]] +==== `[.contract-item-name]#++PluginSetupAlreadyInPreviousRelease++#++(uint8 release, uint16 build, address pluginSetup)++` [.item-kind]#error# + +Thrown if the same plugin setup contract exists already in a previous releases. + +[.contract-item] +[[PluginRepo-EmptyReleaseMetadata--]] +==== `[.contract-item-name]#++EmptyReleaseMetadata++#++()++` [.item-kind]#error# + +Thrown if the metadata URI is empty. + +[.contract-item] +[[PluginRepo-ReleaseDoesNotExist--]] +==== `[.contract-item-name]#++ReleaseDoesNotExist++#++()++` [.item-kind]#error# + +Thrown if release does not exist. + +[.contract-item] +[[PluginRepo-buildsPerRelease-mapping-uint8----uint16-]] +==== `mapping(uint8 => uint16) [.contract-item-name]#++buildsPerRelease++#` [.item-kind]#internal# + +The mapping between release and build numbers. + +[.contract-item] +[[PluginRepo-versions-mapping-bytes32----struct-PluginRepo-Version-]] +==== `mapping(bytes32 => struct PluginRepo.Version) [.contract-item-name]#++versions++#` [.item-kind]#internal# + +The mapping between the version hash and the corresponding version information. + +[.contract-item] +[[PluginRepo-latestTagHashForPluginSetup-mapping-address----bytes32-]] +==== `mapping(address => bytes32) [.contract-item-name]#++latestTagHashForPluginSetup++#` [.item-kind]#internal# + +The mapping between the plugin setup address and its corresponding version hash. + +:APPLY_INSTALLATION_PERMISSION_ID: pass:normal[xref:#PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32[`++APPLY_INSTALLATION_PERMISSION_ID++`]] +:APPLY_UPDATE_PERMISSION_ID: pass:normal[xref:#PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32[`++APPLY_UPDATE_PERMISSION_ID++`]] +:APPLY_UNINSTALLATION_PERMISSION_ID: pass:normal[xref:#PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32[`++APPLY_UNINSTALLATION_PERMISSION_ID++`]] +:PluginState: pass:normal[xref:#PluginSetupProcessor-PluginState[`++PluginState++`]] +:states: pass:normal[xref:#PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState-[`++states++`]] +:PrepareInstallationParams: pass:normal[xref:#PluginSetupProcessor-PrepareInstallationParams[`++PrepareInstallationParams++`]] +:ApplyInstallationParams: pass:normal[xref:#PluginSetupProcessor-ApplyInstallationParams[`++ApplyInstallationParams++`]] +:PrepareUpdateParams: pass:normal[xref:#PluginSetupProcessor-PrepareUpdateParams[`++PrepareUpdateParams++`]] +:ApplyUpdateParams: pass:normal[xref:#PluginSetupProcessor-ApplyUpdateParams[`++ApplyUpdateParams++`]] +:PrepareUninstallationParams: pass:normal[xref:#PluginSetupProcessor-PrepareUninstallationParams[`++PrepareUninstallationParams++`]] +:ApplyUninstallationParams: pass:normal[xref:#PluginSetupProcessor-ApplyUninstallationParams[`++ApplyUninstallationParams++`]] +:repoRegistry: pass:normal[xref:#PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry[`++repoRegistry++`]] +:SetupApplicationUnauthorized: pass:normal[xref:#PluginSetupProcessor-SetupApplicationUnauthorized-address-address-bytes32-[`++SetupApplicationUnauthorized++`]] +:PluginNonupgradeable: pass:normal[xref:#PluginSetupProcessor-PluginNonupgradeable-address-[`++PluginNonupgradeable++`]] +:PluginProxyUpgradeFailed: pass:normal[xref:#PluginSetupProcessor-PluginProxyUpgradeFailed-address-address-bytes-[`++PluginProxyUpgradeFailed++`]] +:IPluginNotSupported: pass:normal[xref:#PluginSetupProcessor-IPluginNotSupported-address-[`++IPluginNotSupported++`]] +:PluginRepoNonexistent: pass:normal[xref:#PluginSetupProcessor-PluginRepoNonexistent--[`++PluginRepoNonexistent++`]] +:SetupAlreadyPrepared: pass:normal[xref:#PluginSetupProcessor-SetupAlreadyPrepared-bytes32-[`++SetupAlreadyPrepared++`]] +:SetupNotApplicable: pass:normal[xref:#PluginSetupProcessor-SetupNotApplicable-bytes32-[`++SetupNotApplicable++`]] +:InvalidUpdateVersion: pass:normal[xref:#PluginSetupProcessor-InvalidUpdateVersion-struct-PluginRepo-Tag-struct-PluginRepo-Tag-[`++InvalidUpdateVersion++`]] +:PluginAlreadyInstalled: pass:normal[xref:#PluginSetupProcessor-PluginAlreadyInstalled--[`++PluginAlreadyInstalled++`]] +:InvalidAppliedSetupId: pass:normal[xref:#PluginSetupProcessor-InvalidAppliedSetupId-bytes32-bytes32-[`++InvalidAppliedSetupId++`]] +:InstallationPrepared: pass:normal[xref:#PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData-[`++InstallationPrepared++`]] +:InstallationApplied: pass:normal[xref:#PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32-[`++InstallationApplied++`]] +:UpdatePrepared: pass:normal[xref:#PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes-[`++UpdatePrepared++`]] +:UpdateApplied: pass:normal[xref:#PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32-[`++UpdateApplied++`]] +:UninstallationPrepared: pass:normal[xref:#PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission---[`++UninstallationPrepared++`]] +:UninstallationApplied: pass:normal[xref:#PluginSetupProcessor-UninstallationApplied-address-address-bytes32-[`++UninstallationApplied++`]] +:canApply: pass:normal[xref:#PluginSetupProcessor-canApply-address-bytes32-[`++canApply++`]] +:constructor: pass:normal[xref:#PluginSetupProcessor-constructor-contract-PluginRepoRegistry-[`++constructor++`]] +:prepareInstallation: pass:normal[xref:#PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams-[`++prepareInstallation++`]] +:applyInstallation: pass:normal[xref:#PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams-[`++applyInstallation++`]] +:prepareUpdate: pass:normal[xref:#PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams-[`++prepareUpdate++`]] +:applyUpdate: pass:normal[xref:#PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams-[`++applyUpdate++`]] +:prepareUninstallation: pass:normal[xref:#PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams-[`++prepareUninstallation++`]] +:applyUninstallation: pass:normal[xref:#PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams-[`++applyUninstallation++`]] +:validatePreparedSetupId: pass:normal[xref:#PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32-[`++validatePreparedSetupId++`]] + +[.contract] +[[PluginSetupProcessor]] +=== `++PluginSetupProcessor++` link:https://github.com/aragon/osx/blob/v1.4.0-rc0/src/framework/plugin/setup/PluginSetupProcessor.sol[{github-icon},role=heading-link] + +This contract is temporarily granted the `ROOT_PERMISSION_ID` permission on the applying DAO and therefore is highly security critical. + +[.contract-index] +.Modifiers +-- +* {xref-PluginSetupProcessor-canApply-address-bytes32-}[`++canApply(_dao, _permissionId)++`] + +-- + +[.contract-index] +.Functions +-- +* {xref-PluginSetupProcessor-constructor-contract-PluginRepoRegistry-}[`++constructor(_repoRegistry)++`] +* {xref-PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams-}[`++prepareInstallation(_dao, _params)++`] +* {xref-PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams-}[`++applyInstallation(_dao, _params)++`] +* {xref-PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams-}[`++prepareUpdate(_dao, _params)++`] +* {xref-PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams-}[`++applyUpdate(_dao, _params)++`] +* {xref-PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams-}[`++prepareUninstallation(_dao, _params)++`] +* {xref-PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams-}[`++applyUninstallation(_dao, _params)++`] +* {xref-PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32-}[`++validatePreparedSetupId(pluginInstallationId, preparedSetupId)++`] +* {xref-PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32}[`++APPLY_INSTALLATION_PERMISSION_ID()++`] +* {xref-PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32}[`++APPLY_UPDATE_PERMISSION_ID()++`] +* {xref-PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32}[`++APPLY_UNINSTALLATION_PERMISSION_ID()++`] +* {xref-PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState-}[`++states()++`] +* {xref-PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry}[`++repoRegistry()++`] + +[.contract-subindex-inherited] +.ProtocolVersion +* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] + +[.contract-subindex-inherited] +.IProtocolVersion + +-- + +[.contract-index] +.Events +-- +* {xref-PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData-}[`++InstallationPrepared(sender, dao, preparedSetupId, pluginSetupRepo, versionTag, data, plugin, preparedSetupData)++`] +* {xref-PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32-}[`++InstallationApplied(dao, plugin, preparedSetupId, appliedSetupId)++`] +* {xref-PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes-}[`++UpdatePrepared(sender, dao, preparedSetupId, pluginSetupRepo, versionTag, setupPayload, preparedSetupData, initData)++`] +* {xref-PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32-}[`++UpdateApplied(dao, plugin, preparedSetupId, appliedSetupId)++`] +* {xref-PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission---}[`++UninstallationPrepared(sender, dao, preparedSetupId, pluginSetupRepo, versionTag, setupPayload, permissions)++`] +* {xref-PluginSetupProcessor-UninstallationApplied-address-address-bytes32-}[`++UninstallationApplied(dao, plugin, preparedSetupId)++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +-- + +[.contract-index] +.Errors +-- +* {xref-PluginSetupProcessor-SetupApplicationUnauthorized-address-address-bytes32-}[`++SetupApplicationUnauthorized(dao, caller, permissionId)++`] +* {xref-PluginSetupProcessor-PluginNonupgradeable-address-}[`++PluginNonupgradeable(plugin)++`] +* {xref-PluginSetupProcessor-PluginProxyUpgradeFailed-address-address-bytes-}[`++PluginProxyUpgradeFailed(proxy, implementation, initData)++`] +* {xref-PluginSetupProcessor-IPluginNotSupported-address-}[`++IPluginNotSupported(plugin)++`] +* {xref-PluginSetupProcessor-PluginRepoNonexistent--}[`++PluginRepoNonexistent()++`] +* {xref-PluginSetupProcessor-SetupAlreadyPrepared-bytes32-}[`++SetupAlreadyPrepared(preparedSetupId)++`] +* {xref-PluginSetupProcessor-SetupNotApplicable-bytes32-}[`++SetupNotApplicable(preparedSetupId)++`] +* {xref-PluginSetupProcessor-InvalidUpdateVersion-struct-PluginRepo-Tag-struct-PluginRepo-Tag-}[`++InvalidUpdateVersion(currentVersionTag, newVersionTag)++`] +* {xref-PluginSetupProcessor-PluginAlreadyInstalled--}[`++PluginAlreadyInstalled()++`] +* {xref-PluginSetupProcessor-InvalidAppliedSetupId-bytes32-bytes32-}[`++InvalidAppliedSetupId(currentAppliedSetupId, appliedSetupId)++`] + +[.contract-subindex-inherited] +.ProtocolVersion + +[.contract-subindex-inherited] +.IProtocolVersion + +-- + +[.contract-item] +[[PluginSetupProcessor-canApply-address-bytes32-]] +==== `[.contract-item-name]#++canApply++#++(address _dao, bytes32 _permissionId)++` [.item-kind]#modifier# + +A modifier to check if a caller has the permission to apply a prepared setup. + +[.contract-item] +[[PluginSetupProcessor-constructor-contract-PluginRepoRegistry-]] +==== `[.contract-item-name]#++constructor++#++(contract PluginRepoRegistry _repoRegistry)++` [.item-kind]#public# + +Constructs the plugin setup processor by setting the associated plugin repo registry. + +[.contract-item] +[[PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams-]] +==== `[.contract-item-name]#++prepareInstallation++#++(address _dao, struct PluginSetupProcessor.PrepareInstallationParams _params) → address plugin, struct IPluginSetup.PreparedSetupData preparedSetupData++` [.item-kind]#external# + +Prepares the installation of a plugin. + +[.contract-item] +[[PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams-]] +==== `[.contract-item-name]#++applyInstallation++#++(address _dao, struct PluginSetupProcessor.ApplyInstallationParams _params)++` [.item-kind]#external# + +Applies the permissions of a prepared installation to a DAO. + +[.contract-item] +[[PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams-]] +==== `[.contract-item-name]#++prepareUpdate++#++(address _dao, struct PluginSetupProcessor.PrepareUpdateParams _params) → bytes initData, struct IPluginSetup.PreparedSetupData preparedSetupData++` [.item-kind]#external# + +Prepares the update of an UUPS upgradeable plugin. + +The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happened) on which the update is prepared for. + +[.contract-item] +[[PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams-]] +==== `[.contract-item-name]#++applyUpdate++#++(address _dao, struct PluginSetupProcessor.ApplyUpdateParams _params)++` [.item-kind]#external# + +Applies the permissions of a prepared update of an UUPS upgradeable proxy contract to a DAO. + +[.contract-item] +[[PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams-]] +==== `[.contract-item-name]#++prepareUninstallation++#++(address _dao, struct PluginSetupProcessor.PrepareUninstallationParams _params) → struct PermissionLib.MultiTargetPermission[] permissions++` [.item-kind]#external# + +Prepares the uninstallation of a plugin. + +The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happened) on which the uninstallation was prepared for. + +[.contract-item] +[[PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams-]] +==== `[.contract-item-name]#++applyUninstallation++#++(address _dao, struct PluginSetupProcessor.ApplyUninstallationParams _params)++` [.item-kind]#external# + +Applies the permissions of a prepared uninstallation to a DAO. + +The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happened) on which the uninstallation was prepared for. + +[.contract-item] +[[PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32-]] +==== `[.contract-item-name]#++validatePreparedSetupId++#++(bytes32 pluginInstallationId, bytes32 preparedSetupId)++` [.item-kind]#public# + +Validates that a setup ID can be applied for `applyInstallation`, `applyUpdate`, or `applyUninstallation`. + +If the block number stored in `states[pluginInstallationId].blockNumber` exceeds the one stored in `pluginState.preparedSetupIdToBlockNumber[preparedSetupId]`, the prepared setup with `preparedSetupId` is outdated and not applicable anymore. + +[.contract-item] +[[PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++APPLY_INSTALLATION_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `applyInstallation` function. + +[.contract-item] +[[PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++APPLY_UPDATE_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `applyUpdate` function. + +[.contract-item] +[[PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32]] +==== `[.contract-item-name]#++APPLY_UNINSTALLATION_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# + +The ID of the permission required to call the `applyUninstallation` function. + +[.contract-item] +[[PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState-]] +==== `[.contract-item-name]#++states++#++() → mapping(bytes32 => struct PluginSetupProcessor.PluginState)++` [.item-kind]#public# + +A mapping between the plugin installation ID (obtained from the DAO and plugin address) and the plugin state information. + +This variable is public on purpose to allow future versions to access and migrate the storage. + +[.contract-item] +[[PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry]] +==== `[.contract-item-name]#++repoRegistry++#++() → contract PluginRepoRegistry++` [.item-kind]#public# + +The plugin repo registry listing the `PluginRepo` contracts versioning the `PluginSetup` contracts. + +[.contract-item] +[[PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData-]] +==== `[.contract-item-name]#++InstallationPrepared++#++(address indexed sender, address indexed dao, bytes32 preparedSetupId, contract PluginRepo indexed pluginSetupRepo, struct PluginRepo.Tag versionTag, bytes data, address plugin, struct IPluginSetup.PreparedSetupData preparedSetupData)++` [.item-kind]#event# + +Emitted with a prepared plugin installation to store data relevant for the application step. + +[.contract-item] +[[PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32-]] +==== `[.contract-item-name]#++InstallationApplied++#++(address indexed dao, address indexed plugin, bytes32 preparedSetupId, bytes32 appliedSetupId)++` [.item-kind]#event# + +Emitted after a plugin installation was applied. + +[.contract-item] +[[PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes-]] +==== `[.contract-item-name]#++UpdatePrepared++#++(address indexed sender, address indexed dao, bytes32 preparedSetupId, contract PluginRepo indexed pluginSetupRepo, struct PluginRepo.Tag versionTag, struct IPluginSetup.SetupPayload setupPayload, struct IPluginSetup.PreparedSetupData preparedSetupData, bytes initData)++` [.item-kind]#event# + +Emitted with a prepared plugin update to store data relevant for the application step. + +[.contract-item] +[[PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32-]] +==== `[.contract-item-name]#++UpdateApplied++#++(address indexed dao, address indexed plugin, bytes32 preparedSetupId, bytes32 appliedSetupId)++` [.item-kind]#event# + +Emitted after a plugin update was applied. + +[.contract-item] +[[PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission---]] +==== `[.contract-item-name]#++UninstallationPrepared++#++(address indexed sender, address indexed dao, bytes32 preparedSetupId, contract PluginRepo indexed pluginSetupRepo, struct PluginRepo.Tag versionTag, struct IPluginSetup.SetupPayload setupPayload, struct PermissionLib.MultiTargetPermission[] permissions)++` [.item-kind]#event# + +Emitted with a prepared plugin uninstallation to store data relevant for the application step. + +[.contract-item] +[[PluginSetupProcessor-UninstallationApplied-address-address-bytes32-]] +==== `[.contract-item-name]#++UninstallationApplied++#++(address indexed dao, address indexed plugin, bytes32 preparedSetupId)++` [.item-kind]#event# + +Emitted after a plugin installation was applied. + +[.contract-item] +[[PluginSetupProcessor-SetupApplicationUnauthorized-address-address-bytes32-]] +==== `[.contract-item-name]#++SetupApplicationUnauthorized++#++(address dao, address caller, bytes32 permissionId)++` [.item-kind]#error# + +Thrown if a setup is unauthorized and cannot be applied because of a missing permission of the associated DAO. + +This is thrown if the `APPLY_INSTALLATION_PERMISSION_ID`, `APPLY_UPDATE_PERMISSION_ID`, or APPLY_UNINSTALLATION_PERMISSION_ID is missing. + +[.contract-item] +[[PluginSetupProcessor-PluginNonupgradeable-address-]] +==== `[.contract-item-name]#++PluginNonupgradeable++#++(address plugin)++` [.item-kind]#error# + +Thrown if a plugin is not upgradeable. + +[.contract-item] +[[PluginSetupProcessor-PluginProxyUpgradeFailed-address-address-bytes-]] +==== `[.contract-item-name]#++PluginProxyUpgradeFailed++#++(address proxy, address implementation, bytes initData)++` [.item-kind]#error# + +Thrown if the upgrade of an `UUPSUpgradeable` proxy contract (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)) failed. + +[.contract-item] +[[PluginSetupProcessor-IPluginNotSupported-address-]] +==== `[.contract-item-name]#++IPluginNotSupported++#++(address plugin)++` [.item-kind]#error# + +Thrown if a contract does not support the `IPlugin` interface. + +[.contract-item] +[[PluginSetupProcessor-PluginRepoNonexistent--]] +==== `[.contract-item-name]#++PluginRepoNonexistent++#++()++` [.item-kind]#error# + +Thrown if a plugin repository does not exist on the plugin repo registry. + +[.contract-item] +[[PluginSetupProcessor-SetupAlreadyPrepared-bytes32-]] +==== `[.contract-item-name]#++SetupAlreadyPrepared++#++(bytes32 preparedSetupId)++` [.item-kind]#error# + +Thrown if a plugin setup was already prepared indicated by the prepared setup ID. + +[.contract-item] +[[PluginSetupProcessor-SetupNotApplicable-bytes32-]] +==== `[.contract-item-name]#++SetupNotApplicable++#++(bytes32 preparedSetupId)++` [.item-kind]#error# + +Thrown if a prepared setup ID is not eligible to be applied. This can happen if another setup has been already applied or if the setup wasn't prepared in the first place. + +[.contract-item] +[[PluginSetupProcessor-InvalidUpdateVersion-struct-PluginRepo-Tag-struct-PluginRepo-Tag-]] +==== `[.contract-item-name]#++InvalidUpdateVersion++#++(struct PluginRepo.Tag currentVersionTag, struct PluginRepo.Tag newVersionTag)++` [.item-kind]#error# + +Thrown if the update version is invalid. + +[.contract-item] +[[PluginSetupProcessor-PluginAlreadyInstalled--]] +==== `[.contract-item-name]#++PluginAlreadyInstalled++#++()++` [.item-kind]#error# + +Thrown if plugin is already installed and one tries to prepare or apply install on it. + +[.contract-item] +[[PluginSetupProcessor-InvalidAppliedSetupId-bytes32-bytes32-]] +==== `[.contract-item-name]#++InvalidAppliedSetupId++#++(bytes32 currentAppliedSetupId, bytes32 appliedSetupId)++` [.item-kind]#error# + +Thrown if the applied setup ID resulting from the supplied setup payload does not match with the current applied setup ID. + diff --git a/packages/contracts/docs/modules/api/pages/osx-contracts.adoc b/packages/contracts/docs/modules/api/pages/osx-contracts.adoc deleted file mode 100644 index fd910f239..000000000 --- a/packages/contracts/docs/modules/api/pages/osx-contracts.adoc +++ /dev/null @@ -1,2466 +0,0 @@ -:github-icon: pass:[] -:xref-DAO-nonReentrant--: xref:osx-contracts.adoc#DAO-nonReentrant-- -:xref-DAO-onlyCallAtInitialization--: xref:osx-contracts.adoc#DAO-onlyCallAtInitialization-- -:xref-DAO-constructor--: xref:osx-contracts.adoc#DAO-constructor-- -:xref-DAO-initialize-bytes-address-address-string-: xref:osx-contracts.adoc#DAO-initialize-bytes-address-address-string- -:xref-DAO-initializeFrom-uint8-3--bytes-: xref:osx-contracts.adoc#DAO-initializeFrom-uint8-3--bytes- -:xref-DAO-isPermissionRestrictedForAnyAddr-bytes32-: xref:osx-contracts.adoc#DAO-isPermissionRestrictedForAnyAddr-bytes32- -:xref-DAO-_authorizeUpgrade-address-: xref:osx-contracts.adoc#DAO-_authorizeUpgrade-address- -:xref-DAO-setTrustedForwarder-address-: xref:osx-contracts.adoc#DAO-setTrustedForwarder-address- -:xref-DAO-getTrustedForwarder--: xref:osx-contracts.adoc#DAO-getTrustedForwarder-- -:xref-DAO-hasPermission-address-address-bytes32-bytes-: xref:osx-contracts.adoc#DAO-hasPermission-address-address-bytes32-bytes- -:xref-DAO-setMetadata-bytes-: xref:osx-contracts.adoc#DAO-setMetadata-bytes- -:xref-DAO-execute-bytes32-struct-Action---uint256-: xref:osx-contracts.adoc#DAO-execute-bytes32-struct-Action---uint256- -:xref-DAO-deposit-address-uint256-string-: xref:osx-contracts.adoc#DAO-deposit-address-uint256-string- -:xref-DAO-setSignatureValidator-address-: xref:osx-contracts.adoc#DAO-setSignatureValidator-address- -:xref-DAO-isValidSignature-bytes32-bytes-: xref:osx-contracts.adoc#DAO-isValidSignature-bytes32-bytes- -:xref-DAO-receive--: xref:osx-contracts.adoc#DAO-receive-- -:xref-DAO-fallback-bytes-: xref:osx-contracts.adoc#DAO-fallback-bytes- -:xref-DAO-_setMetadata-bytes-: xref:osx-contracts.adoc#DAO-_setMetadata-bytes- -:xref-DAO-_setTrustedForwarder-address-: xref:osx-contracts.adoc#DAO-_setTrustedForwarder-address- -:xref-DAO-registerStandardCallback-bytes4-bytes4-bytes4-: xref:osx-contracts.adoc#DAO-registerStandardCallback-bytes4-bytes4-bytes4- -:xref-DAO-daoURI--: xref:osx-contracts.adoc#DAO-daoURI-- -:xref-DAO-setDaoURI-string-: xref:osx-contracts.adoc#DAO-setDaoURI-string- -:xref-DAO-_setDaoURI-string-: xref:osx-contracts.adoc#DAO-_setDaoURI-string- -:xref-DAO-EXECUTE_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#DAO-EXECUTE_PERMISSION_ID-bytes32 -:xref-DAO-UPGRADE_DAO_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#DAO-UPGRADE_DAO_PERMISSION_ID-bytes32 -:xref-DAO-SET_METADATA_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#DAO-SET_METADATA_PERMISSION_ID-bytes32 -:xref-DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32 -:xref-DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32 -:xref-DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32 -:xref-CallbackHandler-_handleCallback-bytes4-bytes-: xref:osx-contracts.adoc#CallbackHandler-_handleCallback-bytes4-bytes- -:xref-CallbackHandler-_registerCallback-bytes4-bytes4-: xref:osx-contracts.adoc#CallbackHandler-_registerCallback-bytes4-bytes4- -:xref-PermissionManager-__PermissionManager_init-address-: xref:osx-contracts.adoc#PermissionManager-__PermissionManager_init-address- -:xref-PermissionManager-grant-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-grant-address-address-bytes32- -:xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:osx-contracts.adoc#PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition- -:xref-PermissionManager-revoke-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-revoke-address-address-bytes32- -:xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---: xref:osx-contracts.adoc#PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission--- -:xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---: xref:osx-contracts.adoc#PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission--- -:xref-PermissionManager-isGranted-address-address-bytes32-bytes-: xref:osx-contracts.adoc#PermissionManager-isGranted-address-address-bytes32-bytes- -:xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-: xref:osx-contracts.adoc#PermissionManager-_checkCondition-address-address-address-bytes32-bytes- -:xref-PermissionManager-_initializePermissionManager-address-: xref:osx-contracts.adoc#PermissionManager-_initializePermissionManager-address- -:xref-PermissionManager-_grant-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-_grant-address-address-bytes32- -:xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:osx-contracts.adoc#PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition- -:xref-PermissionManager-_revoke-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-_revoke-address-address-bytes32- -:xref-PermissionManager-_auth-bytes32-: xref:osx-contracts.adoc#PermissionManager-_auth-bytes32- -:xref-PermissionManager-permissionHash-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-permissionHash-address-address-bytes32- -:xref-PermissionManager-ROOT_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PermissionManager-ROOT_PERMISSION_ID-bytes32 -:xref-DAO-NewURI-string-: xref:osx-contracts.adoc#DAO-NewURI-string- -:xref-CallbackHandler-CallbackReceived-address-bytes4-bytes-: xref:osx-contracts.adoc#CallbackHandler-CallbackReceived-address-bytes4-bytes- -:xref-PermissionManager-Granted-bytes32-address-address-address-address-: xref:osx-contracts.adoc#PermissionManager-Granted-bytes32-address-address-address-address- -:xref-PermissionManager-Revoked-bytes32-address-address-address-: xref:osx-contracts.adoc#PermissionManager-Revoked-bytes32-address-address-address- -:xref-PermissionManager-auth-bytes32-: xref:osx-contracts.adoc#PermissionManager-auth-bytes32- -:xref-PermissionManager-__PermissionManager_init-address-: xref:osx-contracts.adoc#PermissionManager-__PermissionManager_init-address- -:xref-PermissionManager-grant-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-grant-address-address-bytes32- -:xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:osx-contracts.adoc#PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition- -:xref-PermissionManager-revoke-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-revoke-address-address-bytes32- -:xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---: xref:osx-contracts.adoc#PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission--- -:xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---: xref:osx-contracts.adoc#PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission--- -:xref-PermissionManager-isGranted-address-address-bytes32-bytes-: xref:osx-contracts.adoc#PermissionManager-isGranted-address-address-bytes32-bytes- -:xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-: xref:osx-contracts.adoc#PermissionManager-_checkCondition-address-address-address-bytes32-bytes- -:xref-PermissionManager-_initializePermissionManager-address-: xref:osx-contracts.adoc#PermissionManager-_initializePermissionManager-address- -:xref-PermissionManager-_grant-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-_grant-address-address-bytes32- -:xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:osx-contracts.adoc#PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition- -:xref-PermissionManager-_revoke-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-_revoke-address-address-bytes32- -:xref-PermissionManager-_auth-bytes32-: xref:osx-contracts.adoc#PermissionManager-_auth-bytes32- -:xref-PermissionManager-permissionHash-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-permissionHash-address-address-bytes32- -:xref-PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-: xref:osx-contracts.adoc#PermissionManager-isPermissionRestrictedForAnyAddr-bytes32- -:xref-PermissionManager-ROOT_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PermissionManager-ROOT_PERMISSION_ID-bytes32 -:xref-PermissionManager-Granted-bytes32-address-address-address-address-: xref:osx-contracts.adoc#PermissionManager-Granted-bytes32-address-address-address-address- -:xref-PermissionManager-Revoked-bytes32-address-address-address-: xref:osx-contracts.adoc#PermissionManager-Revoked-bytes32-address-address-address- -:xref-CallbackHandler-_handleCallback-bytes4-bytes-: xref:osx-contracts.adoc#CallbackHandler-_handleCallback-bytes4-bytes- -:xref-CallbackHandler-_registerCallback-bytes4-bytes4-: xref:osx-contracts.adoc#CallbackHandler-_registerCallback-bytes4-bytes4- -:xref-CallbackHandler-CallbackReceived-address-bytes4-bytes-: xref:osx-contracts.adoc#CallbackHandler-CallbackReceived-address-bytes4-bytes- -:xref-DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor-: xref:osx-contracts.adoc#DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor- -:xref-DAOFactory-supportsInterface-bytes4-: xref:osx-contracts.adoc#DAOFactory-supportsInterface-bytes4- -:xref-DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings---: xref:osx-contracts.adoc#DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings--- -:xref-DAOFactory-_createDAO-struct-DAOFactory-DAOSettings-: xref:osx-contracts.adoc#DAOFactory-_createDAO-struct-DAOFactory-DAOSettings- -:xref-DAOFactory-_setDAOPermissions-address-: xref:osx-contracts.adoc#DAOFactory-_setDAOPermissions-address- -:xref-DAOFactory-daoBase-address: xref:osx-contracts.adoc#DAOFactory-daoBase-address -:xref-DAOFactory-daoRegistry-contract-DAORegistry: xref:osx-contracts.adoc#DAOFactory-daoRegistry-contract-DAORegistry -:xref-DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor: xref:osx-contracts.adoc#DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor -:xref-PluginRepoFactory-constructor-contract-PluginRepoRegistry-: xref:osx-contracts.adoc#PluginRepoFactory-constructor-contract-PluginRepoRegistry- -:xref-PluginRepoFactory-supportsInterface-bytes4-: xref:osx-contracts.adoc#PluginRepoFactory-supportsInterface-bytes4- -:xref-PluginRepoFactory-createPluginRepo-string-address-: xref:osx-contracts.adoc#PluginRepoFactory-createPluginRepo-string-address- -:xref-PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes-: xref:osx-contracts.adoc#PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes- -:xref-PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address-: xref:osx-contracts.adoc#PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address- -:xref-PluginRepoFactory-_createPluginRepo-string-address-: xref:osx-contracts.adoc#PluginRepoFactory-_createPluginRepo-string-address- -:xref-PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry: xref:osx-contracts.adoc#PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry -:xref-PluginRepoFactory-pluginRepoBase-address: xref:osx-contracts.adoc#PluginRepoFactory-pluginRepoBase-address -:xref-DAORegistry-constructor--: xref:osx-contracts.adoc#DAORegistry-constructor-- -:xref-DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-: xref:osx-contracts.adoc#DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar- -:xref-DAORegistry-register-contract-IDAO-address-string-: xref:osx-contracts.adoc#DAORegistry-register-contract-IDAO-address-string- -:xref-DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32 -:xref-DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar: xref:osx-contracts.adoc#DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar -:xref-InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4-: xref:osx-contracts.adoc#InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4- -:xref-InterfaceBasedRegistry-_authorizeUpgrade-address-: xref:osx-contracts.adoc#InterfaceBasedRegistry-_authorizeUpgrade-address- -:xref-InterfaceBasedRegistry-_register-address-: xref:osx-contracts.adoc#InterfaceBasedRegistry-_register-address- -:xref-InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32 -:xref-InterfaceBasedRegistry-targetInterfaceId-bytes4: xref:osx-contracts.adoc#InterfaceBasedRegistry-targetInterfaceId-bytes4 -:xref-InterfaceBasedRegistry-entries-mapping-address----bool-: xref:osx-contracts.adoc#InterfaceBasedRegistry-entries-mapping-address----bool- -:xref-DAORegistry-DAORegistered-address-address-string-: xref:osx-contracts.adoc#DAORegistry-DAORegistered-address-address-string- -:xref-PluginRepoRegistry-constructor--: xref:osx-contracts.adoc#PluginRepoRegistry-constructor-- -:xref-PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-: xref:osx-contracts.adoc#PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar- -:xref-PluginRepoRegistry-registerPluginRepo-string-address-: xref:osx-contracts.adoc#PluginRepoRegistry-registerPluginRepo-string-address- -:xref-PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32 -:xref-PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar: xref:osx-contracts.adoc#PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar -:xref-InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4-: xref:osx-contracts.adoc#InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4- -:xref-InterfaceBasedRegistry-_authorizeUpgrade-address-: xref:osx-contracts.adoc#InterfaceBasedRegistry-_authorizeUpgrade-address- -:xref-InterfaceBasedRegistry-_register-address-: xref:osx-contracts.adoc#InterfaceBasedRegistry-_register-address- -:xref-InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32 -:xref-InterfaceBasedRegistry-targetInterfaceId-bytes4: xref:osx-contracts.adoc#InterfaceBasedRegistry-targetInterfaceId-bytes4 -:xref-InterfaceBasedRegistry-entries-mapping-address----bool-: xref:osx-contracts.adoc#InterfaceBasedRegistry-entries-mapping-address----bool- -:xref-PluginRepoRegistry-PluginRepoRegistered-string-address-: xref:osx-contracts.adoc#PluginRepoRegistry-PluginRepoRegistered-string-address- -:xref-PluginRepo-constructor--: xref:osx-contracts.adoc#PluginRepo-constructor-- -:xref-PluginRepo-initialize-address-: xref:osx-contracts.adoc#PluginRepo-initialize-address- -:xref-PluginRepo-initializeFrom-uint8-3--bytes-: xref:osx-contracts.adoc#PluginRepo-initializeFrom-uint8-3--bytes- -:xref-PluginRepo-createVersion-uint8-address-bytes-bytes-: xref:osx-contracts.adoc#PluginRepo-createVersion-uint8-address-bytes-bytes- -:xref-PluginRepo-updateReleaseMetadata-uint8-bytes-: xref:osx-contracts.adoc#PluginRepo-updateReleaseMetadata-uint8-bytes- -:xref-PluginRepo-getLatestVersion-uint8-: xref:osx-contracts.adoc#PluginRepo-getLatestVersion-uint8- -:xref-PluginRepo-getLatestVersion-address-: xref:osx-contracts.adoc#PluginRepo-getLatestVersion-address- -:xref-PluginRepo-getVersion-struct-PluginRepo-Tag-: xref:osx-contracts.adoc#PluginRepo-getVersion-struct-PluginRepo-Tag- -:xref-PluginRepo-getVersion-bytes32-: xref:osx-contracts.adoc#PluginRepo-getVersion-bytes32- -:xref-PluginRepo-buildCount-uint8-: xref:osx-contracts.adoc#PluginRepo-buildCount-uint8- -:xref-PluginRepo-tagHash-struct-PluginRepo-Tag-: xref:osx-contracts.adoc#PluginRepo-tagHash-struct-PluginRepo-Tag- -:xref-PluginRepo-_authorizeUpgrade-address-: xref:osx-contracts.adoc#PluginRepo-_authorizeUpgrade-address- -:xref-PluginRepo-supportsInterface-bytes4-: xref:osx-contracts.adoc#PluginRepo-supportsInterface-bytes4- -:xref-PluginRepo-MAINTAINER_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PluginRepo-MAINTAINER_PERMISSION_ID-bytes32 -:xref-PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32 -:xref-PluginRepo-latestRelease-uint8: xref:osx-contracts.adoc#PluginRepo-latestRelease-uint8 -:xref-PermissionManager-__PermissionManager_init-address-: xref:osx-contracts.adoc#PermissionManager-__PermissionManager_init-address- -:xref-PermissionManager-grant-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-grant-address-address-bytes32- -:xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:osx-contracts.adoc#PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition- -:xref-PermissionManager-revoke-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-revoke-address-address-bytes32- -:xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---: xref:osx-contracts.adoc#PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission--- -:xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---: xref:osx-contracts.adoc#PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission--- -:xref-PermissionManager-isGranted-address-address-bytes32-bytes-: xref:osx-contracts.adoc#PermissionManager-isGranted-address-address-bytes32-bytes- -:xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-: xref:osx-contracts.adoc#PermissionManager-_checkCondition-address-address-address-bytes32-bytes- -:xref-PermissionManager-_initializePermissionManager-address-: xref:osx-contracts.adoc#PermissionManager-_initializePermissionManager-address- -:xref-PermissionManager-_grant-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-_grant-address-address-bytes32- -:xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-: xref:osx-contracts.adoc#PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition- -:xref-PermissionManager-_revoke-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-_revoke-address-address-bytes32- -:xref-PermissionManager-_auth-bytes32-: xref:osx-contracts.adoc#PermissionManager-_auth-bytes32- -:xref-PermissionManager-permissionHash-address-address-bytes32-: xref:osx-contracts.adoc#PermissionManager-permissionHash-address-address-bytes32- -:xref-PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-: xref:osx-contracts.adoc#PermissionManager-isPermissionRestrictedForAnyAddr-bytes32- -:xref-PermissionManager-ROOT_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PermissionManager-ROOT_PERMISSION_ID-bytes32 -:xref-PermissionManager-Granted-bytes32-address-address-address-address-: xref:osx-contracts.adoc#PermissionManager-Granted-bytes32-address-address-address-address- -:xref-PermissionManager-Revoked-bytes32-address-address-address-: xref:osx-contracts.adoc#PermissionManager-Revoked-bytes32-address-address-address- -:xref-IPluginRepo-VersionCreated-uint8-uint16-address-bytes-: xref:osx-contracts.adoc#IPluginRepo-VersionCreated-uint8-uint16-address-bytes- -:xref-IPluginRepo-ReleaseMetadataUpdated-uint8-bytes-: xref:osx-contracts.adoc#IPluginRepo-ReleaseMetadataUpdated-uint8-bytes- -:xref-PluginSetupProcessor-canApply-address-bytes32-: xref:osx-contracts.adoc#PluginSetupProcessor-canApply-address-bytes32- -:xref-PluginSetupProcessor-constructor-contract-PluginRepoRegistry-: xref:osx-contracts.adoc#PluginSetupProcessor-constructor-contract-PluginRepoRegistry- -:xref-PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams-: xref:osx-contracts.adoc#PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams- -:xref-PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams-: xref:osx-contracts.adoc#PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams- -:xref-PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams-: xref:osx-contracts.adoc#PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams- -:xref-PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams-: xref:osx-contracts.adoc#PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams- -:xref-PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams-: xref:osx-contracts.adoc#PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams- -:xref-PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams-: xref:osx-contracts.adoc#PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams- -:xref-PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32-: xref:osx-contracts.adoc#PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32- -:xref-PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32 -:xref-PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32 -:xref-PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32: xref:osx-contracts.adoc#PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32 -:xref-PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState-: xref:osx-contracts.adoc#PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState- -:xref-PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry: xref:osx-contracts.adoc#PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry -:xref-PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData-: xref:osx-contracts.adoc#PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData- -:xref-PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32-: xref:osx-contracts.adoc#PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32- -:xref-PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes-: xref:osx-contracts.adoc#PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes- -:xref-PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32-: xref:osx-contracts.adoc#PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32- -:xref-PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission---: xref:osx-contracts.adoc#PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission--- -:xref-PluginSetupProcessor-UninstallationApplied-address-address-bytes32-: xref:osx-contracts.adoc#PluginSetupProcessor-UninstallationApplied-address-address-bytes32- -= OSX - -This is the reference guide of the link:https://github.com/aragon/osx[osx contracts] package. - -== Core - -:EXECUTE_PERMISSION_ID: pass:normal[xref:#DAO-EXECUTE_PERMISSION_ID-bytes32[`++EXECUTE_PERMISSION_ID++`]] -:UPGRADE_DAO_PERMISSION_ID: pass:normal[xref:#DAO-UPGRADE_DAO_PERMISSION_ID-bytes32[`++UPGRADE_DAO_PERMISSION_ID++`]] -:SET_METADATA_PERMISSION_ID: pass:normal[xref:#DAO-SET_METADATA_PERMISSION_ID-bytes32[`++SET_METADATA_PERMISSION_ID++`]] -:SET_TRUSTED_FORWARDER_PERMISSION_ID: pass:normal[xref:#DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32[`++SET_TRUSTED_FORWARDER_PERMISSION_ID++`]] -:REGISTER_STANDARD_CALLBACK_PERMISSION_ID: pass:normal[xref:#DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32[`++REGISTER_STANDARD_CALLBACK_PERMISSION_ID++`]] -:VALIDATE_SIGNATURE_PERMISSION_ID: pass:normal[xref:#DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32[`++VALIDATE_SIGNATURE_PERMISSION_ID++`]] -:MAX_ACTIONS: pass:normal[xref:#DAO-MAX_ACTIONS-uint256[`++MAX_ACTIONS++`]] -:ReentrantCall: pass:normal[xref:#DAO-ReentrantCall--[`++ReentrantCall++`]] -:TooManyActions: pass:normal[xref:#DAO-TooManyActions--[`++TooManyActions++`]] -:ActionFailed: pass:normal[xref:#DAO-ActionFailed-uint256-[`++ActionFailed++`]] -:InsufficientGas: pass:normal[xref:#DAO-InsufficientGas--[`++InsufficientGas++`]] -:ZeroAmount: pass:normal[xref:#DAO-ZeroAmount--[`++ZeroAmount++`]] -:NativeTokenDepositAmountMismatch: pass:normal[xref:#DAO-NativeTokenDepositAmountMismatch-uint256-uint256-[`++NativeTokenDepositAmountMismatch++`]] -:ProtocolVersionUpgradeNotSupported: pass:normal[xref:#DAO-ProtocolVersionUpgradeNotSupported-uint8-3--[`++ProtocolVersionUpgradeNotSupported++`]] -:FunctionRemoved: pass:normal[xref:#DAO-FunctionRemoved--[`++FunctionRemoved++`]] -:AlreadyInitialized: pass:normal[xref:#DAO-AlreadyInitialized--[`++AlreadyInitialized++`]] -:NewURI: pass:normal[xref:#DAO-NewURI-string-[`++NewURI++`]] -:nonReentrant: pass:normal[xref:#DAO-nonReentrant--[`++nonReentrant++`]] -:onlyCallAtInitialization: pass:normal[xref:#DAO-onlyCallAtInitialization--[`++onlyCallAtInitialization++`]] -:constructor: pass:normal[xref:#DAO-constructor--[`++constructor++`]] -:initialize: pass:normal[xref:#DAO-initialize-bytes-address-address-string-[`++initialize++`]] -:initializeFrom: pass:normal[xref:#DAO-initializeFrom-uint8-3--bytes-[`++initializeFrom++`]] -:isPermissionRestrictedForAnyAddr: pass:normal[xref:#DAO-isPermissionRestrictedForAnyAddr-bytes32-[`++isPermissionRestrictedForAnyAddr++`]] -:_authorizeUpgrade: pass:normal[xref:#DAO-_authorizeUpgrade-address-[`++_authorizeUpgrade++`]] -:setTrustedForwarder: pass:normal[xref:#DAO-setTrustedForwarder-address-[`++setTrustedForwarder++`]] -:getTrustedForwarder: pass:normal[xref:#DAO-getTrustedForwarder--[`++getTrustedForwarder++`]] -:hasPermission: pass:normal[xref:#DAO-hasPermission-address-address-bytes32-bytes-[`++hasPermission++`]] -:setMetadata: pass:normal[xref:#DAO-setMetadata-bytes-[`++setMetadata++`]] -:execute: pass:normal[xref:#DAO-execute-bytes32-struct-Action---uint256-[`++execute++`]] -:deposit: pass:normal[xref:#DAO-deposit-address-uint256-string-[`++deposit++`]] -:setSignatureValidator: pass:normal[xref:#DAO-setSignatureValidator-address-[`++setSignatureValidator++`]] -:isValidSignature: pass:normal[xref:#DAO-isValidSignature-bytes32-bytes-[`++isValidSignature++`]] -:receive: pass:normal[xref:#DAO-receive--[`++receive++`]] -:fallback: pass:normal[xref:#DAO-fallback-bytes-[`++fallback++`]] -:_setMetadata: pass:normal[xref:#DAO-_setMetadata-bytes-[`++_setMetadata++`]] -:_setTrustedForwarder: pass:normal[xref:#DAO-_setTrustedForwarder-address-[`++_setTrustedForwarder++`]] -:registerStandardCallback: pass:normal[xref:#DAO-registerStandardCallback-bytes4-bytes4-bytes4-[`++registerStandardCallback++`]] -:daoURI: pass:normal[xref:#DAO-daoURI--[`++daoURI++`]] -:setDaoURI: pass:normal[xref:#DAO-setDaoURI-string-[`++setDaoURI++`]] -:_setDaoURI: pass:normal[xref:#DAO-_setDaoURI-string-[`++_setDaoURI++`]] - -[.contract] -[[DAO]] -=== `++DAO++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/core/dao/DAO.sol[{github-icon},role=heading-link] - -Public API of the Aragon DAO framework. - -[.contract-index] -.Modifiers --- -* {xref-DAO-nonReentrant--}[`++nonReentrant()++`] -* {xref-DAO-onlyCallAtInitialization--}[`++onlyCallAtInitialization()++`] - --- - -[.contract-index] -.Functions --- -* {xref-DAO-constructor--}[`++constructor()++`] -* {xref-DAO-initialize-bytes-address-address-string-}[`++initialize(_metadata, _initialOwner, _trustedForwarder, daoURI_)++`] -* {xref-DAO-initializeFrom-uint8-3--bytes-}[`++initializeFrom(_previousProtocolVersion, _initData)++`] -* {xref-DAO-isPermissionRestrictedForAnyAddr-bytes32-}[`++isPermissionRestrictedForAnyAddr(_permissionId)++`] -* {xref-DAO-_authorizeUpgrade-address-}[`++_authorizeUpgrade()++`] -* {xref-DAO-setTrustedForwarder-address-}[`++setTrustedForwarder(_newTrustedForwarder)++`] -* {xref-DAO-getTrustedForwarder--}[`++getTrustedForwarder()++`] -* {xref-DAO-hasPermission-address-address-bytes32-bytes-}[`++hasPermission(_where, _who, _permissionId, _data)++`] -* {xref-DAO-setMetadata-bytes-}[`++setMetadata(_metadata)++`] -* {xref-DAO-execute-bytes32-struct-Action---uint256-}[`++execute(_callId, _actions, _allowFailureMap)++`] -* {xref-DAO-deposit-address-uint256-string-}[`++deposit(_token, _amount, _reference)++`] -* {xref-DAO-setSignatureValidator-address-}[`++setSignatureValidator()++`] -* {xref-DAO-isValidSignature-bytes32-bytes-}[`++isValidSignature(_hash, _signature)++`] -* {xref-DAO-receive--}[`++receive()++`] -* {xref-DAO-fallback-bytes-}[`++fallback(_input)++`] -* {xref-DAO-_setMetadata-bytes-}[`++_setMetadata(_metadata)++`] -* {xref-DAO-_setTrustedForwarder-address-}[`++_setTrustedForwarder(_trustedForwarder)++`] -* {xref-DAO-registerStandardCallback-bytes4-bytes4-bytes4-}[`++registerStandardCallback(_interfaceId, _callbackSelector, _magicNumber)++`] -* {xref-DAO-daoURI--}[`++daoURI()++`] -* {xref-DAO-setDaoURI-string-}[`++setDaoURI(newDaoURI)++`] -* {xref-DAO-_setDaoURI-string-}[`++_setDaoURI(daoURI_)++`] -* {xref-DAO-EXECUTE_PERMISSION_ID-bytes32}[`++EXECUTE_PERMISSION_ID()++`] -* {xref-DAO-UPGRADE_DAO_PERMISSION_ID-bytes32}[`++UPGRADE_DAO_PERMISSION_ID()++`] -* {xref-DAO-SET_METADATA_PERMISSION_ID-bytes32}[`++SET_METADATA_PERMISSION_ID()++`] -* {xref-DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32}[`++SET_TRUSTED_FORWARDER_PERMISSION_ID()++`] -* {xref-DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32}[`++REGISTER_STANDARD_CALLBACK_PERMISSION_ID()++`] -* {xref-DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32}[`++VALIDATE_SIGNATURE_PERMISSION_ID()++`] - -[.contract-subindex-inherited] -.CallbackHandler -* {xref-CallbackHandler-_handleCallback-bytes4-bytes-}[`++_handleCallback(_callbackSelector, _data)++`] -* {xref-CallbackHandler-_registerCallback-bytes4-bytes4-}[`++_registerCallback(_callbackSelector, _magicNumber)++`] - -[.contract-subindex-inherited] -.PermissionManager -* {xref-PermissionManager-__PermissionManager_init-address-}[`++__PermissionManager_init(_initialOwner)++`] -* {xref-PermissionManager-grant-address-address-bytes32-}[`++grant(_where, _who, _permissionId)++`] -* {xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++grantWithCondition(_where, _who, _permissionId, _condition)++`] -* {xref-PermissionManager-revoke-address-address-bytes32-}[`++revoke(_where, _who, _permissionId)++`] -* {xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---}[`++applySingleTargetPermissions(_where, items)++`] -* {xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---}[`++applyMultiTargetPermissions(_items)++`] -* {xref-PermissionManager-isGranted-address-address-bytes32-bytes-}[`++isGranted(_where, _who, _permissionId, _data)++`] -* {xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-}[`++_checkCondition(_condition, _where, _who, _permissionId, _data)++`] -* {xref-PermissionManager-_initializePermissionManager-address-}[`++_initializePermissionManager(_initialOwner)++`] -* {xref-PermissionManager-_grant-address-address-bytes32-}[`++_grant(_where, _who, _permissionId)++`] -* {xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++_grantWithCondition(_where, _who, _permissionId, _condition)++`] -* {xref-PermissionManager-_revoke-address-address-bytes32-}[`++_revoke(_where, _who, _permissionId)++`] -* {xref-PermissionManager-_auth-bytes32-}[`++_auth(_permissionId)++`] -* {xref-PermissionManager-permissionHash-address-address-bytes32-}[`++permissionHash(_where, _who, _permissionId)++`] -* {xref-PermissionManager-ROOT_PERMISSION_ID-bytes32}[`++ROOT_PERMISSION_ID()++`] - -[.contract-subindex-inherited] -.ProtocolVersion -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.IExecutor - -[.contract-subindex-inherited] -.IDAO - -[.contract-subindex-inherited] -.ERC165StorageUpgradeable - -[.contract-subindex-inherited] -.ERC165Upgradeable - -[.contract-subindex-inherited] -.IERC165Upgradeable - -[.contract-subindex-inherited] -.IERC1271 - -[.contract-subindex-inherited] -.Initializable - -[.contract-subindex-inherited] -.IEIP4824 - --- - -[.contract-index] -.Events --- -* {xref-DAO-NewURI-string-}[`++NewURI(daoURI)++`] - -[.contract-subindex-inherited] -.CallbackHandler -* {xref-CallbackHandler-CallbackReceived-address-bytes4-bytes-}[`++CallbackReceived(sender, sig, data)++`] - -[.contract-subindex-inherited] -.PermissionManager -* {xref-PermissionManager-Granted-bytes32-address-address-address-address-}[`++Granted(permissionId, here, where, who, condition)++`] -* {xref-PermissionManager-Revoked-bytes32-address-address-address-}[`++Revoked(permissionId, here, where, who)++`] - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.IExecutor -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/executors/IExecutor.sol[Executed] - -[.contract-subindex-inherited] -.IDAO -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[MetadataSet] -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[StandardCallbackRegistered] -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[Deposited] -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[NativeTokenDeposited] -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/dao/IDAO.sol[TrustedForwarderSet] - -[.contract-subindex-inherited] -.ERC165StorageUpgradeable - -[.contract-subindex-inherited] -.ERC165Upgradeable - -[.contract-subindex-inherited] -.IERC165Upgradeable - -[.contract-subindex-inherited] -.IERC1271 - -[.contract-subindex-inherited] -.Initializable - -[.contract-subindex-inherited] -.IEIP4824 - --- - -[.contract-index] -.Errors --- - -[.contract-subindex-inherited] -.CallbackHandler - -[.contract-subindex-inherited] -.PermissionManager - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.IExecutor - -[.contract-subindex-inherited] -.IDAO - -[.contract-subindex-inherited] -.ERC165StorageUpgradeable - -[.contract-subindex-inherited] -.ERC165Upgradeable - -[.contract-subindex-inherited] -.IERC165Upgradeable - -[.contract-subindex-inherited] -.IERC1271 - -[.contract-subindex-inherited] -.Initializable - -[.contract-subindex-inherited] -.IEIP4824 - --- - -[.contract-index] -.Internal Variables --- - -[.contract-subindex-inherited] -.CallbackHandler - -[.contract-subindex-inherited] -.PermissionManager - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.IExecutor - -[.contract-subindex-inherited] -.IDAO - -[.contract-subindex-inherited] -.ERC165StorageUpgradeable - -[.contract-subindex-inherited] -.ERC165Upgradeable - -[.contract-subindex-inherited] -.IERC165Upgradeable - -[.contract-subindex-inherited] -.IERC1271 - -[.contract-subindex-inherited] -.Initializable - -[.contract-subindex-inherited] -.IEIP4824 - --- - -[.contract-item] -[[DAO-nonReentrant--]] -==== `[.contract-item-name]#++nonReentrant++#++()++` [.item-kind]#modifier# - -A modifier to protect a function from calling itself, directly or indirectly (reentrancy). - -Currently, this modifier is only applied to the `execute()` function. If this is used multiple times, private `_beforeNonReentrant()` and `_afterNonReentrant()` functions should be created to prevent code duplication. - -[.contract-item] -[[DAO-onlyCallAtInitialization--]] -==== `[.contract-item-name]#++onlyCallAtInitialization++#++()++` [.item-kind]#modifier# - -This ensures that the initialize function cannot be called during the upgrade process. - -[.contract-item] -[[DAO-constructor--]] -==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#public# - -Disables the initializers on the implementation contract to prevent it from being left uninitialized. - -[.contract-item] -[[DAO-initialize-bytes-address-address-string-]] -==== `[.contract-item-name]#++initialize++#++(bytes _metadata, address _initialOwner, address _trustedForwarder, string daoURI_)++` [.item-kind]#external# - -Initializes the DAO by -- setting the reentrancy status variable to `_NOT_ENTERED` -- registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID -- setting the trusted forwarder for meta transactions -- giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). - -This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). - -[.contract-item] -[[DAO-initializeFrom-uint8-3--bytes-]] -==== `[.contract-item-name]#++initializeFrom++#++(uint8[3] _previousProtocolVersion, bytes _initData)++` [.item-kind]#external# - -Initializes the DAO after an upgrade from a previous protocol version. - -[.contract-item] -[[DAO-isPermissionRestrictedForAnyAddr-bytes32-]] -==== `[.contract-item-name]#++isPermissionRestrictedForAnyAddr++#++(bytes32 _permissionId) → bool++` [.item-kind]#internal# - -Decides if the granting permissionId is restricted when `_who == ANY_ADDR` or `_where == ANY_ADDR`. - -By default, every permission is unrestricted and it is the derived contract's responsibility to override it. Note, that the `ROOT_PERMISSION_ID` is included and not required to be set it again. - -[.contract-item] -[[DAO-_authorizeUpgrade-address-]] -==== `[.contract-item-name]#++_authorizeUpgrade++#++(address)++` [.item-kind]#internal# - -Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). - -The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. - -[.contract-item] -[[DAO-setTrustedForwarder-address-]] -==== `[.contract-item-name]#++setTrustedForwarder++#++(address _newTrustedForwarder)++` [.item-kind]#external# - -Setter for the trusted forwarder verifying the meta transaction. - -[.contract-item] -[[DAO-getTrustedForwarder--]] -==== `[.contract-item-name]#++getTrustedForwarder++#++() → address++` [.item-kind]#external# - -Getter for the trusted forwarder verifying the meta transaction. - -[.contract-item] -[[DAO-hasPermission-address-address-bytes32-bytes-]] -==== `[.contract-item-name]#++hasPermission++#++(address _where, address _who, bytes32 _permissionId, bytes _data) → bool++` [.item-kind]#external# - -Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. - -[.contract-item] -[[DAO-setMetadata-bytes-]] -==== `[.contract-item-name]#++setMetadata++#++(bytes _metadata)++` [.item-kind]#external# - -Updates the DAO metadata (e.g., an IPFS hash). - -[.contract-item] -[[DAO-execute-bytes32-struct-Action---uint256-]] -==== `[.contract-item-name]#++execute++#++(bytes32 _callId, struct Action[] _actions, uint256 _allowFailureMap) → bytes[] execResults, uint256 failureMap++` [.item-kind]#external# - -Executes a list of actions. If a zero allow-failure map is provided, a failing action reverts the entire execution. If a non-zero allow-failure map is provided, allowed actions can fail without the entire call being reverted. - -[.contract-item] -[[DAO-deposit-address-uint256-string-]] -==== `[.contract-item-name]#++deposit++#++(address _token, uint256 _amount, string _reference)++` [.item-kind]#external# - -Deposits (native) tokens to the DAO contract with a reference string. - -[.contract-item] -[[DAO-setSignatureValidator-address-]] -==== `[.contract-item-name]#++setSignatureValidator++#++(address)++` [.item-kind]#external# - -Removed function being left here to not corrupt the IDAO interface ID. Any call will revert. - -Introduced in v1.0.0. Removed in v1.4.0. - -[.contract-item] -[[DAO-isValidSignature-bytes32-bytes-]] -==== `[.contract-item-name]#++isValidSignature++#++(bytes32 _hash, bytes _signature) → bytes4++` [.item-kind]#external# - -Checks whether a signature is valid for a provided hash according to [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271). - -Relays the validation logic determining who is allowed to sign on behalf of the DAO to its permission manager. -Caller specific bypassing can be set direct granting (i.e., `grant({_where: dao, _who: specificErc1271Caller, _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID})`). -Caller specific signature validation logic can be set by granting with a `PermissionCondition` (i.e., `grantWithCondition({_where: dao, _who: specificErc1271Caller, _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID, _condition: yourConditionImplementation})`) -Generic signature validation logic can be set for all calling contracts by granting with a `PermissionCondition` to `PermissionManager.ANY_ADDR()` (i.e., `grantWithCondition({_where: dao, _who: PermissionManager.ANY_ADDR(), _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID, _condition: yourConditionImplementation})`). - -[.contract-item] -[[DAO-receive--]] -==== `[.contract-item-name]#++receive++#++()++` [.item-kind]#external# - -Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. - -This call is bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). -Gas cost increases in future hard forks might break this function. As an alternative, [ERC-2930](https://eips.ethereum.org/EIPS/eip-2930)-type transactions using access lists can be employed. - -[.contract-item] -[[DAO-fallback-bytes-]] -==== `[.contract-item-name]#++fallback++#++(bytes _input) → bytes++` [.item-kind]#external# - -Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. - -[.contract-item] -[[DAO-_setMetadata-bytes-]] -==== `[.contract-item-name]#++_setMetadata++#++(bytes _metadata)++` [.item-kind]#internal# - -Emits the MetadataSet event if new metadata is set. - -[.contract-item] -[[DAO-_setTrustedForwarder-address-]] -==== `[.contract-item-name]#++_setTrustedForwarder++#++(address _trustedForwarder)++` [.item-kind]#internal# - -Sets the trusted forwarder on the DAO and emits the associated event. - -[.contract-item] -[[DAO-registerStandardCallback-bytes4-bytes4-bytes4-]] -==== `[.contract-item-name]#++registerStandardCallback++#++(bytes4 _interfaceId, bytes4 _callbackSelector, bytes4 _magicNumber)++` [.item-kind]#external# - -Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. - -[.contract-item] -[[DAO-daoURI--]] -==== `[.contract-item-name]#++daoURI++#++() → string++` [.item-kind]#external# - -A distinct Uniform Resource Identifier (URI) pointing to a JSON object following the "EIP-4824 DAO JSON-LD Schema". This JSON file splits into four URIs: membersURI, proposalsURI, activityLogURI, and governanceURI. The membersURI should point to a JSON file that conforms to the "EIP-4824 Members JSON-LD Schema". The proposalsURI should point to a JSON file that conforms to the "EIP-4824 Proposals JSON-LD Schema". The activityLogURI should point to a JSON file that conforms to the "EIP-4824 Activity Log JSON-LD Schema". The governanceURI should point to a flatfile, normatively a .md file. Each of the JSON files named above can be statically hosted or dynamically-generated. - -[.contract-item] -[[DAO-setDaoURI-string-]] -==== `[.contract-item-name]#++setDaoURI++#++(string newDaoURI)++` [.item-kind]#external# - -Updates the set DAO URI to a new value. - -[.contract-item] -[[DAO-_setDaoURI-string-]] -==== `[.contract-item-name]#++_setDaoURI++#++(string daoURI_)++` [.item-kind]#internal# - -Sets the new [ERC-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI and emits the associated event. - -[.contract-item] -[[DAO-EXECUTE_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++EXECUTE_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `execute` function. - -[.contract-item] -[[DAO-UPGRADE_DAO_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++UPGRADE_DAO_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `_authorizeUpgrade` function. - -[.contract-item] -[[DAO-SET_METADATA_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++SET_METADATA_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `setMetadata` function. - -[.contract-item] -[[DAO-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++SET_TRUSTED_FORWARDER_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `setTrustedForwarder` function. - -[.contract-item] -[[DAO-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++REGISTER_STANDARD_CALLBACK_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `registerStandardCallback` function. - -[.contract-item] -[[DAO-VALIDATE_SIGNATURE_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++VALIDATE_SIGNATURE_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to validate [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signatures. - -[.contract-item] -[[DAO-NewURI-string-]] -==== `[.contract-item-name]#++NewURI++#++(string daoURI)++` [.item-kind]#event# - -Emitted when a new DAO URI is set. - -[.contract-item] -[[DAO-ReentrantCall--]] -==== `[.contract-item-name]#++ReentrantCall++#++()++` [.item-kind]#error# - -Thrown if a call is reentrant. - -[.contract-item] -[[DAO-TooManyActions--]] -==== `[.contract-item-name]#++TooManyActions++#++()++` [.item-kind]#error# - -Thrown if the action array length is larger than `MAX_ACTIONS`. - -[.contract-item] -[[DAO-ActionFailed-uint256-]] -==== `[.contract-item-name]#++ActionFailed++#++(uint256 index)++` [.item-kind]#error# - -Thrown if action execution has failed. - -[.contract-item] -[[DAO-InsufficientGas--]] -==== `[.contract-item-name]#++InsufficientGas++#++()++` [.item-kind]#error# - -Thrown if an action has insufficient gas left. - -[.contract-item] -[[DAO-ZeroAmount--]] -==== `[.contract-item-name]#++ZeroAmount++#++()++` [.item-kind]#error# - -Thrown if the deposit amount is zero. - -[.contract-item] -[[DAO-NativeTokenDepositAmountMismatch-uint256-uint256-]] -==== `[.contract-item-name]#++NativeTokenDepositAmountMismatch++#++(uint256 expected, uint256 actual)++` [.item-kind]#error# - -Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. - -[.contract-item] -[[DAO-ProtocolVersionUpgradeNotSupported-uint8-3--]] -==== `[.contract-item-name]#++ProtocolVersionUpgradeNotSupported++#++(uint8[3] protocolVersion)++` [.item-kind]#error# - -Thrown if an upgrade is not supported from a specific protocol version . - -[.contract-item] -[[DAO-FunctionRemoved--]] -==== `[.contract-item-name]#++FunctionRemoved++#++()++` [.item-kind]#error# - -Thrown when a function is removed but left to not corrupt the interface ID. - -[.contract-item] -[[DAO-AlreadyInitialized--]] -==== `[.contract-item-name]#++AlreadyInitialized++#++()++` [.item-kind]#error# - -Thrown when initialize is called after it has already been executed. - -[.contract-item] -[[DAO-MAX_ACTIONS-uint256]] -==== `uint256 [.contract-item-name]#++MAX_ACTIONS++#` [.item-kind]#internal constant# - -The internal constant storing the maximal action array length. - -:ROOT_PERMISSION_ID: pass:normal[xref:#PermissionManager-ROOT_PERMISSION_ID-bytes32[`++ROOT_PERMISSION_ID++`]] -:ANY_ADDR: pass:normal[xref:#PermissionManager-ANY_ADDR-address[`++ANY_ADDR++`]] -:UNSET_FLAG: pass:normal[xref:#PermissionManager-UNSET_FLAG-address[`++UNSET_FLAG++`]] -:ALLOW_FLAG: pass:normal[xref:#PermissionManager-ALLOW_FLAG-address[`++ALLOW_FLAG++`]] -:permissionsHashed: pass:normal[xref:#PermissionManager-permissionsHashed-mapping-bytes32----address-[`++permissionsHashed++`]] -:Unauthorized: pass:normal[xref:#PermissionManager-Unauthorized-address-address-bytes32-[`++Unauthorized++`]] -:PermissionAlreadyGrantedForDifferentCondition: pass:normal[xref:#PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-[`++PermissionAlreadyGrantedForDifferentCondition++`]] -:ConditionNotAContract: pass:normal[xref:#PermissionManager-ConditionNotAContract-contract-IPermissionCondition-[`++ConditionNotAContract++`]] -:ConditionInterfaceNotSupported: pass:normal[xref:#PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-[`++ConditionInterfaceNotSupported++`]] -:PermissionsForAnyAddressDisallowed: pass:normal[xref:#PermissionManager-PermissionsForAnyAddressDisallowed--[`++PermissionsForAnyAddressDisallowed++`]] -:AnyAddressDisallowedForWhoAndWhere: pass:normal[xref:#PermissionManager-AnyAddressDisallowedForWhoAndWhere--[`++AnyAddressDisallowedForWhoAndWhere++`]] -:GrantWithConditionNotSupported: pass:normal[xref:#PermissionManager-GrantWithConditionNotSupported--[`++GrantWithConditionNotSupported++`]] -:Granted: pass:normal[xref:#PermissionManager-Granted-bytes32-address-address-address-address-[`++Granted++`]] -:Revoked: pass:normal[xref:#PermissionManager-Revoked-bytes32-address-address-address-[`++Revoked++`]] -:auth: pass:normal[xref:#PermissionManager-auth-bytes32-[`++auth++`]] -:__PermissionManager_init: pass:normal[xref:#PermissionManager-__PermissionManager_init-address-[`++__PermissionManager_init++`]] -:grant: pass:normal[xref:#PermissionManager-grant-address-address-bytes32-[`++grant++`]] -:grantWithCondition: pass:normal[xref:#PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-[`++grantWithCondition++`]] -:revoke: pass:normal[xref:#PermissionManager-revoke-address-address-bytes32-[`++revoke++`]] -:applySingleTargetPermissions: pass:normal[xref:#PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---[`++applySingleTargetPermissions++`]] -:applyMultiTargetPermissions: pass:normal[xref:#PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---[`++applyMultiTargetPermissions++`]] -:isGranted: pass:normal[xref:#PermissionManager-isGranted-address-address-bytes32-bytes-[`++isGranted++`]] -:_checkCondition: pass:normal[xref:#PermissionManager-_checkCondition-address-address-address-bytes32-bytes-[`++_checkCondition++`]] -:_initializePermissionManager: pass:normal[xref:#PermissionManager-_initializePermissionManager-address-[`++_initializePermissionManager++`]] -:_grant: pass:normal[xref:#PermissionManager-_grant-address-address-bytes32-[`++_grant++`]] -:_grantWithCondition: pass:normal[xref:#PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-[`++_grantWithCondition++`]] -:_revoke: pass:normal[xref:#PermissionManager-_revoke-address-address-bytes32-[`++_revoke++`]] -:_auth: pass:normal[xref:#PermissionManager-_auth-bytes32-[`++_auth++`]] -:permissionHash: pass:normal[xref:#PermissionManager-permissionHash-address-address-bytes32-[`++permissionHash++`]] -:isPermissionRestrictedForAnyAddr: pass:normal[xref:#PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-[`++isPermissionRestrictedForAnyAddr++`]] - -[.contract] -[[PermissionManager]] -=== `++PermissionManager++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/core/permission/PermissionManager.sol[{github-icon},role=heading-link] - -[.contract-index] -.Modifiers --- -* {xref-PermissionManager-auth-bytes32-}[`++auth(_permissionId)++`] - --- - -[.contract-index] -.Functions --- -* {xref-PermissionManager-__PermissionManager_init-address-}[`++__PermissionManager_init(_initialOwner)++`] -* {xref-PermissionManager-grant-address-address-bytes32-}[`++grant(_where, _who, _permissionId)++`] -* {xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++grantWithCondition(_where, _who, _permissionId, _condition)++`] -* {xref-PermissionManager-revoke-address-address-bytes32-}[`++revoke(_where, _who, _permissionId)++`] -* {xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---}[`++applySingleTargetPermissions(_where, items)++`] -* {xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---}[`++applyMultiTargetPermissions(_items)++`] -* {xref-PermissionManager-isGranted-address-address-bytes32-bytes-}[`++isGranted(_where, _who, _permissionId, _data)++`] -* {xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-}[`++_checkCondition(_condition, _where, _who, _permissionId, _data)++`] -* {xref-PermissionManager-_initializePermissionManager-address-}[`++_initializePermissionManager(_initialOwner)++`] -* {xref-PermissionManager-_grant-address-address-bytes32-}[`++_grant(_where, _who, _permissionId)++`] -* {xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++_grantWithCondition(_where, _who, _permissionId, _condition)++`] -* {xref-PermissionManager-_revoke-address-address-bytes32-}[`++_revoke(_where, _who, _permissionId)++`] -* {xref-PermissionManager-_auth-bytes32-}[`++_auth(_permissionId)++`] -* {xref-PermissionManager-permissionHash-address-address-bytes32-}[`++permissionHash(_where, _who, _permissionId)++`] -* {xref-PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-}[`++isPermissionRestrictedForAnyAddr(_permissionId)++`] -* {xref-PermissionManager-ROOT_PERMISSION_ID-bytes32}[`++ROOT_PERMISSION_ID()++`] - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Events --- -* {xref-PermissionManager-Granted-bytes32-address-address-address-address-}[`++Granted(permissionId, here, where, who, condition)++`] -* {xref-PermissionManager-Revoked-bytes32-address-address-address-}[`++Revoked(permissionId, here, where, who)++`] - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Errors --- - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Internal Variables --- - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-item] -[[PermissionManager-auth-bytes32-]] -==== `[.contract-item-name]#++auth++#++(bytes32 _permissionId)++` [.item-kind]#modifier# - -A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through this permission manager. - -[.contract-item] -[[PermissionManager-__PermissionManager_init-address-]] -==== `[.contract-item-name]#++__PermissionManager_init++#++(address _initialOwner)++` [.item-kind]#internal# - -Initialization method to set the initial owner of the permission manager. - -The initial owner is granted the `ROOT_PERMISSION_ID` permission. - -[.contract-item] -[[PermissionManager-grant-address-address-bytes32-]] -==== `[.contract-item-name]#++grant++#++(address _where, address _who, bytes32 _permissionId)++` [.item-kind]#external# - -Grants permission to an address to call methods in a contract guarded by an auth modifier with the specified permission identifier. - -Requires the `ROOT_PERMISSION_ID` permission. -Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. - -[.contract-item] -[[PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-]] -==== `[.contract-item-name]#++grantWithCondition++#++(address _where, address _who, bytes32 _permissionId, contract IPermissionCondition _condition)++` [.item-kind]#external# - -Grants permission to an address to call methods in a target contract guarded by an auth modifier with the specified permission identifier if the referenced condition permits it. - -Requires the `ROOT_PERMISSION_ID` permission -Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. - -[.contract-item] -[[PermissionManager-revoke-address-address-bytes32-]] -==== `[.contract-item-name]#++revoke++#++(address _where, address _who, bytes32 _permissionId)++` [.item-kind]#external# - -Revokes permission from an address to call methods in a target contract guarded by an auth modifier with the specified permission identifier. - -Requires the `ROOT_PERMISSION_ID` permission. -Note, that revoking permissions with `_who` or `_where` equal to `ANY_ADDR` does not revoke other permissions with specific `_who` and `_where` addresses that exist in parallel. - -[.contract-item] -[[PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---]] -==== `[.contract-item-name]#++applySingleTargetPermissions++#++(address _where, struct PermissionLib.SingleTargetPermission[] items)++` [.item-kind]#external# - -Applies an array of permission operations on a single target contracts `_where`. - -[.contract-item] -[[PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---]] -==== `[.contract-item-name]#++applyMultiTargetPermissions++#++(struct PermissionLib.MultiTargetPermission[] _items)++` [.item-kind]#external# - -Applies an array of permission operations on multiple target contracts `items[i].where`. - -[.contract-item] -[[PermissionManager-isGranted-address-address-bytes32-bytes-]] -==== `[.contract-item-name]#++isGranted++#++(address _where, address _who, bytes32 _permissionId, bytes _data) → bool++` [.item-kind]#public# - -Checks if the caller address has permission on the target contract via a permission identifier and relays the answer to a condition contract if this was declared during the granting process. - -[.contract-item] -[[PermissionManager-_checkCondition-address-address-address-bytes32-bytes-]] -==== `[.contract-item-name]#++_checkCondition++#++(address _condition, address _where, address _who, bytes32 _permissionId, bytes _data) → bool++` [.item-kind]#internal# - -Relays the question if caller address has permission on target contract via a permission identifier to a condition contract. -Checks a condition contract by doing an external call via try/catch. - -If the external call fails, we return `false`. - -[.contract-item] -[[PermissionManager-_initializePermissionManager-address-]] -==== `[.contract-item-name]#++_initializePermissionManager++#++(address _initialOwner)++` [.item-kind]#internal# - -Grants the `ROOT_PERMISSION_ID` permission to the initial owner during initialization of the permission manager. - -[.contract-item] -[[PermissionManager-_grant-address-address-bytes32-]] -==== `[.contract-item-name]#++_grant++#++(address _where, address _who, bytes32 _permissionId)++` [.item-kind]#internal# - -This method is used in the external `grant` method of the permission manager. - -Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. - -[.contract-item] -[[PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-]] -==== `[.contract-item-name]#++_grantWithCondition++#++(address _where, address _who, bytes32 _permissionId, contract IPermissionCondition _condition)++` [.item-kind]#internal# - -This method is used in the external `grantWithCondition` method of the permission manager. - -Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. - -[.contract-item] -[[PermissionManager-_revoke-address-address-bytes32-]] -==== `[.contract-item-name]#++_revoke++#++(address _where, address _who, bytes32 _permissionId)++` [.item-kind]#internal# - -This method is used in the public `revoke` method of the permission manager. - -Note, that revoking permissions with `_who` or `_where` equal to `ANY_ADDR` does not revoke other permissions with specific `_who` and `_where` addresses that might have been granted in parallel. - -[.contract-item] -[[PermissionManager-_auth-bytes32-]] -==== `[.contract-item-name]#++_auth++#++(bytes32 _permissionId)++` [.item-kind]#internal# - -A private function to be used to check permissions on the permission manager contract (`address(this)`) itself. - -[.contract-item] -[[PermissionManager-permissionHash-address-address-bytes32-]] -==== `[.contract-item-name]#++permissionHash++#++(address _where, address _who, bytes32 _permissionId) → bytes32++` [.item-kind]#internal# - -Generates the hash for the `permissionsHashed` mapping obtained from the word "PERMISSION", the contract address, the address owning the permission, and the permission identifier. - -[.contract-item] -[[PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-]] -==== `[.contract-item-name]#++isPermissionRestrictedForAnyAddr++#++(bytes32 _permissionId) → bool++` [.item-kind]#internal# - -Decides if the granting permissionId is restricted when `_who == ANY_ADDR` or `_where == ANY_ADDR`. - -By default, every permission is unrestricted and it is the derived contract's responsibility to override it. Note, that the `ROOT_PERMISSION_ID` is included and not required to be set it again. - -[.contract-item] -[[PermissionManager-ROOT_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++ROOT_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `grant`, `grantWithCondition`, `revoke`, and `bulk` function. - -[.contract-item] -[[PermissionManager-Granted-bytes32-address-address-address-address-]] -==== `[.contract-item-name]#++Granted++#++(bytes32 indexed permissionId, address indexed here, address where, address indexed who, address condition)++` [.item-kind]#event# - -Emitted when a permission `permission` is granted in the context `here` to the address `_who` for the contract `_where`. - -[.contract-item] -[[PermissionManager-Revoked-bytes32-address-address-address-]] -==== `[.contract-item-name]#++Revoked++#++(bytes32 indexed permissionId, address indexed here, address where, address indexed who)++` [.item-kind]#event# - -Emitted when a permission `permission` is revoked in the context `here` from the address `_who` for the contract `_where`. - -[.contract-item] -[[PermissionManager-Unauthorized-address-address-bytes32-]] -==== `[.contract-item-name]#++Unauthorized++#++(address where, address who, bytes32 permissionId)++` [.item-kind]#error# - -Thrown if a call is unauthorized. - -[.contract-item] -[[PermissionManager-PermissionAlreadyGrantedForDifferentCondition-address-address-bytes32-address-address-]] -==== `[.contract-item-name]#++PermissionAlreadyGrantedForDifferentCondition++#++(address where, address who, bytes32 permissionId, address currentCondition, address newCondition)++` [.item-kind]#error# - -Thrown if a permission has been already granted with a different condition. - -This makes sure that condition on the same permission can not be overwriten by a different condition. - -[.contract-item] -[[PermissionManager-ConditionNotAContract-contract-IPermissionCondition-]] -==== `[.contract-item-name]#++ConditionNotAContract++#++(contract IPermissionCondition condition)++` [.item-kind]#error# - -Thrown if a condition address is not a contract. - -[.contract-item] -[[PermissionManager-ConditionInterfaceNotSupported-contract-IPermissionCondition-]] -==== `[.contract-item-name]#++ConditionInterfaceNotSupported++#++(contract IPermissionCondition condition)++` [.item-kind]#error# - -Thrown if a condition contract does not support the `IPermissionCondition` interface. - -[.contract-item] -[[PermissionManager-PermissionsForAnyAddressDisallowed--]] -==== `[.contract-item-name]#++PermissionsForAnyAddressDisallowed++#++()++` [.item-kind]#error# - -Thrown for `ROOT_PERMISSION_ID` or `EXECUTE_PERMISSION_ID` permission grants where `who` or `where` is `ANY_ADDR`. - -[.contract-item] -[[PermissionManager-AnyAddressDisallowedForWhoAndWhere--]] -==== `[.contract-item-name]#++AnyAddressDisallowedForWhoAndWhere++#++()++` [.item-kind]#error# - -Thrown for permission grants where `who` and `where` are both `ANY_ADDR`. - -[.contract-item] -[[PermissionManager-GrantWithConditionNotSupported--]] -==== `[.contract-item-name]#++GrantWithConditionNotSupported++#++()++` [.item-kind]#error# - -Thrown if `Operation.GrantWithCondition` is requested as an operation but the method does not support it. - -[.contract-item] -[[PermissionManager-ANY_ADDR-address]] -==== `address [.contract-item-name]#++ANY_ADDR++#` [.item-kind]#internal constant# - -A special address encoding permissions that are valid for any address `who` or `where`. - -[.contract-item] -[[PermissionManager-UNSET_FLAG-address]] -==== `address [.contract-item-name]#++UNSET_FLAG++#` [.item-kind]#internal constant# - -A special address encoding if a permissions is not set and therefore not allowed. - -[.contract-item] -[[PermissionManager-ALLOW_FLAG-address]] -==== `address [.contract-item-name]#++ALLOW_FLAG++#` [.item-kind]#internal constant# - -A special address encoding if a permission is allowed. - -[.contract-item] -[[PermissionManager-permissionsHashed-mapping-bytes32----address-]] -==== `mapping(bytes32 => address) [.contract-item-name]#++permissionsHashed++#` [.item-kind]#internal# - -A mapping storing permissions as hashes (i.e., `permissionHash(where, who, permissionId)`) and their status encoded by an address (unset, allowed, or redirecting to a `PermissionCondition`). - -:callbackMagicNumbers: pass:normal[xref:#CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4-[`++callbackMagicNumbers++`]] -:UNREGISTERED_CALLBACK: pass:normal[xref:#CallbackHandler-UNREGISTERED_CALLBACK-bytes4[`++UNREGISTERED_CALLBACK++`]] -:UnknownCallback: pass:normal[xref:#CallbackHandler-UnknownCallback-bytes4-bytes4-[`++UnknownCallback++`]] -:CallbackReceived: pass:normal[xref:#CallbackHandler-CallbackReceived-address-bytes4-bytes-[`++CallbackReceived++`]] -:_handleCallback: pass:normal[xref:#CallbackHandler-_handleCallback-bytes4-bytes-[`++_handleCallback++`]] -:_registerCallback: pass:normal[xref:#CallbackHandler-_registerCallback-bytes4-bytes4-[`++_registerCallback++`]] - -[.contract] -[[CallbackHandler]] -=== `++CallbackHandler++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/core/utils/CallbackHandler.sol[{github-icon},role=heading-link] - -This callback handling functionality is intended to be used by executor contracts (i.e., `DAO.sol`). - -[.contract-index] -.Functions --- -* {xref-CallbackHandler-_handleCallback-bytes4-bytes-}[`++_handleCallback(_callbackSelector, _data)++`] -* {xref-CallbackHandler-_registerCallback-bytes4-bytes4-}[`++_registerCallback(_callbackSelector, _magicNumber)++`] - --- - -[.contract-index] -.Events --- -* {xref-CallbackHandler-CallbackReceived-address-bytes4-bytes-}[`++CallbackReceived(sender, sig, data)++`] - --- - -[.contract-index] -.Errors --- - --- - -[.contract-index] -.Internal Variables --- - --- - -[.contract-item] -[[CallbackHandler-_handleCallback-bytes4-bytes-]] -==== `[.contract-item-name]#++_handleCallback++#++(bytes4 _callbackSelector, bytes _data) → bytes4++` [.item-kind]#internal# - -Handles callbacks to adaptively support ERC standards. - -This function is supposed to be called via `_handleCallback(msg.sig, msg.data)` in the `fallback()` function of the inheriting contract. - -[.contract-item] -[[CallbackHandler-_registerCallback-bytes4-bytes4-]] -==== `[.contract-item-name]#++_registerCallback++#++(bytes4 _callbackSelector, bytes4 _magicNumber)++` [.item-kind]#internal# - -Registers a magic number for a callback function selector. - -[.contract-item] -[[CallbackHandler-CallbackReceived-address-bytes4-bytes-]] -==== `[.contract-item-name]#++CallbackReceived++#++(address sender, bytes4 indexed sig, bytes data)++` [.item-kind]#event# - -Emitted when `_handleCallback` is called. - -[.contract-item] -[[CallbackHandler-UnknownCallback-bytes4-bytes4-]] -==== `[.contract-item-name]#++UnknownCallback++#++(bytes4 callbackSelector, bytes4 magicNumber)++` [.item-kind]#error# - -Thrown if the callback function is not registered. - -[.contract-item] -[[CallbackHandler-callbackMagicNumbers-mapping-bytes4----bytes4-]] -==== `mapping(bytes4 => bytes4) [.contract-item-name]#++callbackMagicNumbers++#` [.item-kind]#internal# - -A mapping between callback function selectors and magic return numbers. - -[.contract-item] -[[CallbackHandler-UNREGISTERED_CALLBACK-bytes4]] -==== `bytes4 [.contract-item-name]#++UNREGISTERED_CALLBACK++#` [.item-kind]#internal constant# - -The magic number refering to unregistered callbacks. - -== Factories - -:daoBase: pass:normal[xref:#DAOFactory-daoBase-address[`++daoBase++`]] -:daoRegistry: pass:normal[xref:#DAOFactory-daoRegistry-contract-DAORegistry[`++daoRegistry++`]] -:pluginSetupProcessor: pass:normal[xref:#DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor[`++pluginSetupProcessor++`]] -:ROOT_PERMISSION_ID: pass:normal[xref:#DAOFactory-ROOT_PERMISSION_ID-bytes32[`++ROOT_PERMISSION_ID++`]] -:UPGRADE_DAO_PERMISSION_ID: pass:normal[xref:#DAOFactory-UPGRADE_DAO_PERMISSION_ID-bytes32[`++UPGRADE_DAO_PERMISSION_ID++`]] -:SET_TRUSTED_FORWARDER_PERMISSION_ID: pass:normal[xref:#DAOFactory-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32[`++SET_TRUSTED_FORWARDER_PERMISSION_ID++`]] -:SET_METADATA_PERMISSION_ID: pass:normal[xref:#DAOFactory-SET_METADATA_PERMISSION_ID-bytes32[`++SET_METADATA_PERMISSION_ID++`]] -:REGISTER_STANDARD_CALLBACK_PERMISSION_ID: pass:normal[xref:#DAOFactory-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32[`++REGISTER_STANDARD_CALLBACK_PERMISSION_ID++`]] -:EXECUTE_PERMISSION_ID: pass:normal[xref:#DAOFactory-EXECUTE_PERMISSION_ID-bytes32[`++EXECUTE_PERMISSION_ID++`]] -:APPLY_INSTALLATION_PERMISSION_ID: pass:normal[xref:#DAOFactory-APPLY_INSTALLATION_PERMISSION_ID-bytes32[`++APPLY_INSTALLATION_PERMISSION_ID++`]] -:DAOSettings: pass:normal[xref:#DAOFactory-DAOSettings[`++DAOSettings++`]] -:PluginSettings: pass:normal[xref:#DAOFactory-PluginSettings[`++PluginSettings++`]] -:InstalledPlugin: pass:normal[xref:#DAOFactory-InstalledPlugin[`++InstalledPlugin++`]] -:NoPluginProvided: pass:normal[xref:#DAOFactory-NoPluginProvided--[`++NoPluginProvided++`]] -:constructor: pass:normal[xref:#DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor-[`++constructor++`]] -:supportsInterface: pass:normal[xref:#DAOFactory-supportsInterface-bytes4-[`++supportsInterface++`]] -:createDao: pass:normal[xref:#DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings---[`++createDao++`]] -:_createDAO: pass:normal[xref:#DAOFactory-_createDAO-struct-DAOFactory-DAOSettings-[`++_createDAO++`]] -:_setDAOPermissions: pass:normal[xref:#DAOFactory-_setDAOPermissions-address-[`++_setDAOPermissions++`]] - -[.contract] -[[DAOFactory]] -=== `++DAOFactory++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/framework/dao/DAOFactory.sol[{github-icon},role=heading-link] - -[.contract-index] -.Functions --- -* {xref-DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor-}[`++constructor(_registry, _pluginSetupProcessor)++`] -* {xref-DAOFactory-supportsInterface-bytes4-}[`++supportsInterface(_interfaceId)++`] -* {xref-DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings---}[`++createDao(_daoSettings, _pluginSettings)++`] -* {xref-DAOFactory-_createDAO-struct-DAOFactory-DAOSettings-}[`++_createDAO(_daoSettings)++`] -* {xref-DAOFactory-_setDAOPermissions-address-}[`++_setDAOPermissions(_daoAddress)++`] -* {xref-DAOFactory-daoBase-address}[`++daoBase()++`] -* {xref-DAOFactory-daoRegistry-contract-DAORegistry}[`++daoRegistry()++`] -* {xref-DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor}[`++pluginSetupProcessor()++`] - -[.contract-subindex-inherited] -.ProtocolVersion -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.ERC165 - -[.contract-subindex-inherited] -.IERC165 - --- - -[.contract-index] -.Errors --- - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.ERC165 - -[.contract-subindex-inherited] -.IERC165 - --- - -[.contract-index] -.Internal Variables --- - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.ERC165 - -[.contract-subindex-inherited] -.IERC165 - --- - -[.contract-item] -[[DAOFactory-constructor-contract-DAORegistry-contract-PluginSetupProcessor-]] -==== `[.contract-item-name]#++constructor++#++(contract DAORegistry _registry, contract PluginSetupProcessor _pluginSetupProcessor)++` [.item-kind]#public# - -The constructor setting the registry and plugin setup processor and creating the base contracts for the factory. - -[.contract-item] -[[DAOFactory-supportsInterface-bytes4-]] -==== `[.contract-item-name]#++supportsInterface++#++(bytes4 _interfaceId) → bool++` [.item-kind]#public# - -Checks if this or the parent contract supports an interface by its ID. - -[.contract-item] -[[DAOFactory-createDao-struct-DAOFactory-DAOSettings-struct-DAOFactory-PluginSettings---]] -==== `[.contract-item-name]#++createDao++#++(struct DAOFactory.DAOSettings _daoSettings, struct DAOFactory.PluginSettings[] _pluginSettings) → contract DAO createdDao, struct DAOFactory.InstalledPlugin[] installedPlugins++` [.item-kind]#external# - -Creates a new DAO, registers it in the DAO registry, and optionally installs plugins via the plugin setup processor. - -If `_pluginSettings` is empty, the caller is granted `EXECUTE_PERMISSION` on the DAO. - -[.contract-item] -[[DAOFactory-_createDAO-struct-DAOFactory-DAOSettings-]] -==== `[.contract-item-name]#++_createDAO++#++(struct DAOFactory.DAOSettings _daoSettings) → contract DAO dao++` [.item-kind]#internal# - -Deploys a new DAO `ERC1967` proxy, and initialize it with this contract as the initial owner. - -[.contract-item] -[[DAOFactory-_setDAOPermissions-address-]] -==== `[.contract-item-name]#++_setDAOPermissions++#++(address _daoAddress)++` [.item-kind]#internal# - -Sets the required permissions for the new DAO. - -[.contract-item] -[[DAOFactory-daoBase-address]] -==== `[.contract-item-name]#++daoBase++#++() → address++` [.item-kind]#public# - -The DAO base contract, to be used for creating new `DAO`s via `createERC1967Proxy` function. - -[.contract-item] -[[DAOFactory-daoRegistry-contract-DAORegistry]] -==== `[.contract-item-name]#++daoRegistry++#++() → contract DAORegistry++` [.item-kind]#public# - -The DAO registry listing the `DAO` contracts created via this contract. - -[.contract-item] -[[DAOFactory-pluginSetupProcessor-contract-PluginSetupProcessor]] -==== `[.contract-item-name]#++pluginSetupProcessor++#++() → contract PluginSetupProcessor++` [.item-kind]#public# - -The plugin setup processor for installing plugins on the newly created `DAO`s. - -[.contract-item] -[[DAOFactory-NoPluginProvided--]] -==== `[.contract-item-name]#++NoPluginProvided++#++()++` [.item-kind]#error# - -Thrown if `PluginSettings` array is empty, and no plugin is provided. - -[.contract-item] -[[DAOFactory-ROOT_PERMISSION_ID-bytes32]] -==== `bytes32 [.contract-item-name]#++ROOT_PERMISSION_ID++#` [.item-kind]#internal# - -[.contract-item] -[[DAOFactory-UPGRADE_DAO_PERMISSION_ID-bytes32]] -==== `bytes32 [.contract-item-name]#++UPGRADE_DAO_PERMISSION_ID++#` [.item-kind]#internal# - -[.contract-item] -[[DAOFactory-SET_TRUSTED_FORWARDER_PERMISSION_ID-bytes32]] -==== `bytes32 [.contract-item-name]#++SET_TRUSTED_FORWARDER_PERMISSION_ID++#` [.item-kind]#internal# - -[.contract-item] -[[DAOFactory-SET_METADATA_PERMISSION_ID-bytes32]] -==== `bytes32 [.contract-item-name]#++SET_METADATA_PERMISSION_ID++#` [.item-kind]#internal# - -[.contract-item] -[[DAOFactory-REGISTER_STANDARD_CALLBACK_PERMISSION_ID-bytes32]] -==== `bytes32 [.contract-item-name]#++REGISTER_STANDARD_CALLBACK_PERMISSION_ID++#` [.item-kind]#internal# - -[.contract-item] -[[DAOFactory-EXECUTE_PERMISSION_ID-bytes32]] -==== `bytes32 [.contract-item-name]#++EXECUTE_PERMISSION_ID++#` [.item-kind]#internal# - -[.contract-item] -[[DAOFactory-APPLY_INSTALLATION_PERMISSION_ID-bytes32]] -==== `bytes32 [.contract-item-name]#++APPLY_INSTALLATION_PERMISSION_ID++#` [.item-kind]#internal# - -:pluginRepoRegistry: pass:normal[xref:#PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry[`++pluginRepoRegistry++`]] -:pluginRepoBase: pass:normal[xref:#PluginRepoFactory-pluginRepoBase-address[`++pluginRepoBase++`]] -:constructor: pass:normal[xref:#PluginRepoFactory-constructor-contract-PluginRepoRegistry-[`++constructor++`]] -:supportsInterface: pass:normal[xref:#PluginRepoFactory-supportsInterface-bytes4-[`++supportsInterface++`]] -:createPluginRepo: pass:normal[xref:#PluginRepoFactory-createPluginRepo-string-address-[`++createPluginRepo++`]] -:createPluginRepoWithFirstVersion: pass:normal[xref:#PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes-[`++createPluginRepoWithFirstVersion++`]] -:_setPluginRepoPermissions: pass:normal[xref:#PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address-[`++_setPluginRepoPermissions++`]] -:_createPluginRepo: pass:normal[xref:#PluginRepoFactory-_createPluginRepo-string-address-[`++_createPluginRepo++`]] - -[.contract] -[[PluginRepoFactory]] -=== `++PluginRepoFactory++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/framework/plugin/repo/PluginRepoFactory.sol[{github-icon},role=heading-link] - -[.contract-index] -.Functions --- -* {xref-PluginRepoFactory-constructor-contract-PluginRepoRegistry-}[`++constructor(_pluginRepoRegistry)++`] -* {xref-PluginRepoFactory-supportsInterface-bytes4-}[`++supportsInterface(_interfaceId)++`] -* {xref-PluginRepoFactory-createPluginRepo-string-address-}[`++createPluginRepo(_subdomain, _initialOwner)++`] -* {xref-PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes-}[`++createPluginRepoWithFirstVersion(_subdomain, _pluginSetup, _maintainer, _releaseMetadata, _buildMetadata)++`] -* {xref-PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address-}[`++_setPluginRepoPermissions(pluginRepo, maintainer)++`] -* {xref-PluginRepoFactory-_createPluginRepo-string-address-}[`++_createPluginRepo(_subdomain, _initialOwner)++`] -* {xref-PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry}[`++pluginRepoRegistry()++`] -* {xref-PluginRepoFactory-pluginRepoBase-address}[`++pluginRepoBase()++`] - -[.contract-subindex-inherited] -.ProtocolVersion -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.ERC165 - -[.contract-subindex-inherited] -.IERC165 - --- - -[.contract-item] -[[PluginRepoFactory-constructor-contract-PluginRepoRegistry-]] -==== `[.contract-item-name]#++constructor++#++(contract PluginRepoRegistry _pluginRepoRegistry)++` [.item-kind]#public# - -Initializes the addresses of the Aragon plugin registry and `PluginRepo` base contract to proxy to. - -[.contract-item] -[[PluginRepoFactory-supportsInterface-bytes4-]] -==== `[.contract-item-name]#++supportsInterface++#++(bytes4 _interfaceId) → bool++` [.item-kind]#public# - -Checks if this or the parent contract supports an interface by its ID. - -[.contract-item] -[[PluginRepoFactory-createPluginRepo-string-address-]] -==== `[.contract-item-name]#++createPluginRepo++#++(string _subdomain, address _initialOwner) → contract PluginRepo++` [.item-kind]#external# - -Creates a plugin repository proxy pointing to the `pluginRepoBase` implementation and registers it in the Aragon plugin registry. - -[.contract-item] -[[PluginRepoFactory-createPluginRepoWithFirstVersion-string-address-address-bytes-bytes-]] -==== `[.contract-item-name]#++createPluginRepoWithFirstVersion++#++(string _subdomain, address _pluginSetup, address _maintainer, bytes _releaseMetadata, bytes _buildMetadata) → contract PluginRepo pluginRepo++` [.item-kind]#external# - -Creates and registers a `PluginRepo` with an ENS subdomain and publishes an initial version `1.1`. - -After the creation of the `PluginRepo` and release of the first version by the factory, ownership is transferred to the `_maintainer` address. - -[.contract-item] -[[PluginRepoFactory-_setPluginRepoPermissions-contract-PluginRepo-address-]] -==== `[.contract-item-name]#++_setPluginRepoPermissions++#++(contract PluginRepo pluginRepo, address maintainer)++` [.item-kind]#internal# - -Set the final permissions for the published plugin repository maintainer. All permissions are revoked from the plugin factory and granted to the specified plugin maintainer. - -The plugin maintainer is granted the `MAINTAINER_PERMISSION_ID`, `UPGRADE_REPO_PERMISSION_ID`, and `ROOT_PERMISSION_ID`. - -[.contract-item] -[[PluginRepoFactory-_createPluginRepo-string-address-]] -==== `[.contract-item-name]#++_createPluginRepo++#++(string _subdomain, address _initialOwner) → contract PluginRepo pluginRepo++` [.item-kind]#internal# - -Internal method creating a `PluginRepo` via the [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) proxy pattern from the provided base contract and registering it in the Aragon plugin registry. - -Passing an empty `_subdomain` will cause the transaction to revert. - -[.contract-item] -[[PluginRepoFactory-pluginRepoRegistry-contract-PluginRepoRegistry]] -==== `[.contract-item-name]#++pluginRepoRegistry++#++() → contract PluginRepoRegistry++` [.item-kind]#public# - -The Aragon plugin registry contract. - -[.contract-item] -[[PluginRepoFactory-pluginRepoBase-address]] -==== `[.contract-item-name]#++pluginRepoBase++#++() → address++` [.item-kind]#public# - -The address of the `PluginRepo` base contract to proxy to.. - -== Registries - -:REGISTER_DAO_PERMISSION_ID: pass:normal[xref:#DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32[`++REGISTER_DAO_PERMISSION_ID++`]] -:subdomainRegistrar: pass:normal[xref:#DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar[`++subdomainRegistrar++`]] -:InvalidDaoSubdomain: pass:normal[xref:#DAORegistry-InvalidDaoSubdomain-string-[`++InvalidDaoSubdomain++`]] -:DAORegistered: pass:normal[xref:#DAORegistry-DAORegistered-address-address-string-[`++DAORegistered++`]] -:constructor: pass:normal[xref:#DAORegistry-constructor--[`++constructor++`]] -:initialize: pass:normal[xref:#DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-[`++initialize++`]] -:register: pass:normal[xref:#DAORegistry-register-contract-IDAO-address-string-[`++register++`]] - -[.contract] -[[DAORegistry]] -=== `++DAORegistry++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/framework/dao/DAORegistry.sol[{github-icon},role=heading-link] - -[.contract-index] -.Functions --- -* {xref-DAORegistry-constructor--}[`++constructor()++`] -* {xref-DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-}[`++initialize(_managingDao, _subdomainRegistrar)++`] -* {xref-DAORegistry-register-contract-IDAO-address-string-}[`++register(dao, creator, subdomain)++`] -* {xref-DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32}[`++REGISTER_DAO_PERMISSION_ID()++`] -* {xref-DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar}[`++subdomainRegistrar()++`] - -[.contract-subindex-inherited] -.ProtocolVersion -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.InterfaceBasedRegistry -* {xref-InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4-}[`++__InterfaceBasedRegistry_init(_managingDao, _targetInterfaceId)++`] -* {xref-InterfaceBasedRegistry-_authorizeUpgrade-address-}[`++_authorizeUpgrade()++`] -* {xref-InterfaceBasedRegistry-_register-address-}[`++_register(_registrant)++`] -* {xref-InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32}[`++UPGRADE_REGISTRY_PERMISSION_ID()++`] -* {xref-InterfaceBasedRegistry-targetInterfaceId-bytes4}[`++targetInterfaceId()++`] -* {xref-InterfaceBasedRegistry-entries-mapping-address----bool-}[`++entries()++`] - -[.contract-subindex-inherited] -.DaoAuthorizableUpgradeable -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol[__DaoAuthorizableUpgradeable_init] -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol[dao] - -[.contract-subindex-inherited] -.ContextUpgradeable - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Events --- -* {xref-DAORegistry-DAORegistered-address-address-string-}[`++DAORegistered(dao, creator, subdomain)++`] - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.InterfaceBasedRegistry - -[.contract-subindex-inherited] -.DaoAuthorizableUpgradeable - -[.contract-subindex-inherited] -.ContextUpgradeable - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Errors --- - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.InterfaceBasedRegistry - -[.contract-subindex-inherited] -.DaoAuthorizableUpgradeable - -[.contract-subindex-inherited] -.ContextUpgradeable - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-item] -[[DAORegistry-constructor--]] -==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#public# - -Used to disallow initializing the implementation contract by an attacker for extra safety. - -[.contract-item] -[[DAORegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-]] -==== `[.contract-item-name]#++initialize++#++(contract IDAO _managingDao, contract ENSSubdomainRegistrar _subdomainRegistrar)++` [.item-kind]#external# - -Initializes the contract. - -[.contract-item] -[[DAORegistry-register-contract-IDAO-address-string-]] -==== `[.contract-item-name]#++register++#++(contract IDAO dao, address creator, string subdomain)++` [.item-kind]#external# - -Registers a DAO by its address. If a non-empty subdomain name is provided that is not taken already, the DAO becomes the owner of the ENS name. - -A subdomain is unique within the Aragon DAO framework and can get stored here. - -[.contract-item] -[[DAORegistry-REGISTER_DAO_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++REGISTER_DAO_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `register` function. - -[.contract-item] -[[DAORegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar]] -==== `[.contract-item-name]#++subdomainRegistrar++#++() → contract ENSSubdomainRegistrar++` [.item-kind]#public# - -The ENS subdomain registrar registering the DAO subdomains. - -[.contract-item] -[[DAORegistry-DAORegistered-address-address-string-]] -==== `[.contract-item-name]#++DAORegistered++#++(address indexed dao, address indexed creator, string subdomain)++` [.item-kind]#event# - -Emitted when a new DAO is registered. - -[.contract-item] -[[DAORegistry-InvalidDaoSubdomain-string-]] -==== `[.contract-item-name]#++InvalidDaoSubdomain++#++(string subdomain)++` [.item-kind]#error# - -Thrown if the DAO subdomain doesn't match the regex `[0-9a-z\-]` - -:REGISTER_PLUGIN_REPO_PERMISSION_ID: pass:normal[xref:#PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32[`++REGISTER_PLUGIN_REPO_PERMISSION_ID++`]] -:subdomainRegistrar: pass:normal[xref:#PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar[`++subdomainRegistrar++`]] -:PluginRepoRegistered: pass:normal[xref:#PluginRepoRegistry-PluginRepoRegistered-string-address-[`++PluginRepoRegistered++`]] -:InvalidPluginSubdomain: pass:normal[xref:#PluginRepoRegistry-InvalidPluginSubdomain-string-[`++InvalidPluginSubdomain++`]] -:EmptyPluginRepoSubdomain: pass:normal[xref:#PluginRepoRegistry-EmptyPluginRepoSubdomain--[`++EmptyPluginRepoSubdomain++`]] -:constructor: pass:normal[xref:#PluginRepoRegistry-constructor--[`++constructor++`]] -:initialize: pass:normal[xref:#PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-[`++initialize++`]] -:registerPluginRepo: pass:normal[xref:#PluginRepoRegistry-registerPluginRepo-string-address-[`++registerPluginRepo++`]] - -[.contract] -[[PluginRepoRegistry]] -=== `++PluginRepoRegistry++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/framework/plugin/repo/PluginRepoRegistry.sol[{github-icon},role=heading-link] - -[.contract-index] -.Functions --- -* {xref-PluginRepoRegistry-constructor--}[`++constructor()++`] -* {xref-PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-}[`++initialize(_dao, _subdomainRegistrar)++`] -* {xref-PluginRepoRegistry-registerPluginRepo-string-address-}[`++registerPluginRepo(subdomain, pluginRepo)++`] -* {xref-PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32}[`++REGISTER_PLUGIN_REPO_PERMISSION_ID()++`] -* {xref-PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar}[`++subdomainRegistrar()++`] - -[.contract-subindex-inherited] -.ProtocolVersion -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.InterfaceBasedRegistry -* {xref-InterfaceBasedRegistry-__InterfaceBasedRegistry_init-contract-IDAO-bytes4-}[`++__InterfaceBasedRegistry_init(_managingDao, _targetInterfaceId)++`] -* {xref-InterfaceBasedRegistry-_authorizeUpgrade-address-}[`++_authorizeUpgrade()++`] -* {xref-InterfaceBasedRegistry-_register-address-}[`++_register(_registrant)++`] -* {xref-InterfaceBasedRegistry-UPGRADE_REGISTRY_PERMISSION_ID-bytes32}[`++UPGRADE_REGISTRY_PERMISSION_ID()++`] -* {xref-InterfaceBasedRegistry-targetInterfaceId-bytes4}[`++targetInterfaceId()++`] -* {xref-InterfaceBasedRegistry-entries-mapping-address----bool-}[`++entries()++`] - -[.contract-subindex-inherited] -.DaoAuthorizableUpgradeable -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol[__DaoAuthorizableUpgradeable_init] -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol[dao] - -[.contract-subindex-inherited] -.ContextUpgradeable - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Events --- -* {xref-PluginRepoRegistry-PluginRepoRegistered-string-address-}[`++PluginRepoRegistered(subdomain, pluginRepo)++`] - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.InterfaceBasedRegistry - -[.contract-subindex-inherited] -.DaoAuthorizableUpgradeable - -[.contract-subindex-inherited] -.ContextUpgradeable - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Errors --- - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.InterfaceBasedRegistry - -[.contract-subindex-inherited] -.DaoAuthorizableUpgradeable - -[.contract-subindex-inherited] -.ContextUpgradeable - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-item] -[[PluginRepoRegistry-constructor--]] -==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#public# - -Used to disallow initializing the implementation contract by an attacker for extra safety. - -[.contract-item] -[[PluginRepoRegistry-initialize-contract-IDAO-contract-ENSSubdomainRegistrar-]] -==== `[.contract-item-name]#++initialize++#++(contract IDAO _dao, contract ENSSubdomainRegistrar _subdomainRegistrar)++` [.item-kind]#external# - -Initializes the contract by setting calling the `InterfaceBasedRegistry` base class initialize method. - -[.contract-item] -[[PluginRepoRegistry-registerPluginRepo-string-address-]] -==== `[.contract-item-name]#++registerPluginRepo++#++(string subdomain, address pluginRepo)++` [.item-kind]#external# - -Registers a plugin repository with a subdomain and address. - -[.contract-item] -[[PluginRepoRegistry-REGISTER_PLUGIN_REPO_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++REGISTER_PLUGIN_REPO_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `register` function. - -[.contract-item] -[[PluginRepoRegistry-subdomainRegistrar-contract-ENSSubdomainRegistrar]] -==== `[.contract-item-name]#++subdomainRegistrar++#++() → contract ENSSubdomainRegistrar++` [.item-kind]#public# - -The ENS subdomain registrar registering the PluginRepo subdomains. - -[.contract-item] -[[PluginRepoRegistry-PluginRepoRegistered-string-address-]] -==== `[.contract-item-name]#++PluginRepoRegistered++#++(string subdomain, address pluginRepo)++` [.item-kind]#event# - -Emitted if a new plugin repository is registered. - -[.contract-item] -[[PluginRepoRegistry-InvalidPluginSubdomain-string-]] -==== `[.contract-item-name]#++InvalidPluginSubdomain++#++(string subdomain)++` [.item-kind]#error# - -Thrown if the plugin subdomain doesn't match the regex `[0-9a-z\-]` - -[.contract-item] -[[PluginRepoRegistry-EmptyPluginRepoSubdomain--]] -==== `[.contract-item-name]#++EmptyPluginRepoSubdomain++#++()++` [.item-kind]#error# - -Thrown if the plugin repository subdomain is empty. - -== Framework - -:Tag: pass:normal[xref:#PluginRepo-Tag[`++Tag++`]] -:Version: pass:normal[xref:#PluginRepo-Version[`++Version++`]] -:MAINTAINER_PERMISSION_ID: pass:normal[xref:#PluginRepo-MAINTAINER_PERMISSION_ID-bytes32[`++MAINTAINER_PERMISSION_ID++`]] -:UPGRADE_REPO_PERMISSION_ID: pass:normal[xref:#PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32[`++UPGRADE_REPO_PERMISSION_ID++`]] -:buildsPerRelease: pass:normal[xref:#PluginRepo-buildsPerRelease-mapping-uint8----uint16-[`++buildsPerRelease++`]] -:versions: pass:normal[xref:#PluginRepo-versions-mapping-bytes32----struct-PluginRepo-Version-[`++versions++`]] -:latestTagHashForPluginSetup: pass:normal[xref:#PluginRepo-latestTagHashForPluginSetup-mapping-address----bytes32-[`++latestTagHashForPluginSetup++`]] -:latestRelease: pass:normal[xref:#PluginRepo-latestRelease-uint8[`++latestRelease++`]] -:VersionHashDoesNotExist: pass:normal[xref:#PluginRepo-VersionHashDoesNotExist-bytes32-[`++VersionHashDoesNotExist++`]] -:InvalidPluginSetupInterface: pass:normal[xref:#PluginRepo-InvalidPluginSetupInterface--[`++InvalidPluginSetupInterface++`]] -:ReleaseZeroNotAllowed: pass:normal[xref:#PluginRepo-ReleaseZeroNotAllowed--[`++ReleaseZeroNotAllowed++`]] -:InvalidReleaseIncrement: pass:normal[xref:#PluginRepo-InvalidReleaseIncrement-uint8-uint8-[`++InvalidReleaseIncrement++`]] -:PluginSetupAlreadyInPreviousRelease: pass:normal[xref:#PluginRepo-PluginSetupAlreadyInPreviousRelease-uint8-uint16-address-[`++PluginSetupAlreadyInPreviousRelease++`]] -:EmptyReleaseMetadata: pass:normal[xref:#PluginRepo-EmptyReleaseMetadata--[`++EmptyReleaseMetadata++`]] -:ReleaseDoesNotExist: pass:normal[xref:#PluginRepo-ReleaseDoesNotExist--[`++ReleaseDoesNotExist++`]] -:constructor: pass:normal[xref:#PluginRepo-constructor--[`++constructor++`]] -:initialize: pass:normal[xref:#PluginRepo-initialize-address-[`++initialize++`]] -:initializeFrom: pass:normal[xref:#PluginRepo-initializeFrom-uint8-3--bytes-[`++initializeFrom++`]] -:createVersion: pass:normal[xref:#PluginRepo-createVersion-uint8-address-bytes-bytes-[`++createVersion++`]] -:updateReleaseMetadata: pass:normal[xref:#PluginRepo-updateReleaseMetadata-uint8-bytes-[`++updateReleaseMetadata++`]] -:getLatestVersion: pass:normal[xref:#PluginRepo-getLatestVersion-uint8-[`++getLatestVersion++`]] -:getLatestVersion: pass:normal[xref:#PluginRepo-getLatestVersion-address-[`++getLatestVersion++`]] -:getVersion: pass:normal[xref:#PluginRepo-getVersion-struct-PluginRepo-Tag-[`++getVersion++`]] -:getVersion: pass:normal[xref:#PluginRepo-getVersion-bytes32-[`++getVersion++`]] -:buildCount: pass:normal[xref:#PluginRepo-buildCount-uint8-[`++buildCount++`]] -:tagHash: pass:normal[xref:#PluginRepo-tagHash-struct-PluginRepo-Tag-[`++tagHash++`]] -:_authorizeUpgrade: pass:normal[xref:#PluginRepo-_authorizeUpgrade-address-[`++_authorizeUpgrade++`]] -:supportsInterface: pass:normal[xref:#PluginRepo-supportsInterface-bytes4-[`++supportsInterface++`]] - -[.contract] -[[PluginRepo]] -=== `++PluginRepo++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/framework/plugin/repo/PluginRepo.sol[{github-icon},role=heading-link] - -[.contract-index] -.Functions --- -* {xref-PluginRepo-constructor--}[`++constructor()++`] -* {xref-PluginRepo-initialize-address-}[`++initialize(initialOwner)++`] -* {xref-PluginRepo-initializeFrom-uint8-3--bytes-}[`++initializeFrom(_previousProtocolVersion, _initData)++`] -* {xref-PluginRepo-createVersion-uint8-address-bytes-bytes-}[`++createVersion(_release, _pluginSetup, _buildMetadata, _releaseMetadata)++`] -* {xref-PluginRepo-updateReleaseMetadata-uint8-bytes-}[`++updateReleaseMetadata(_release, _releaseMetadata)++`] -* {xref-PluginRepo-getLatestVersion-uint8-}[`++getLatestVersion(_release)++`] -* {xref-PluginRepo-getLatestVersion-address-}[`++getLatestVersion(_pluginSetup)++`] -* {xref-PluginRepo-getVersion-struct-PluginRepo-Tag-}[`++getVersion(_tag)++`] -* {xref-PluginRepo-getVersion-bytes32-}[`++getVersion(_tagHash)++`] -* {xref-PluginRepo-buildCount-uint8-}[`++buildCount(_release)++`] -* {xref-PluginRepo-tagHash-struct-PluginRepo-Tag-}[`++tagHash(_tag)++`] -* {xref-PluginRepo-_authorizeUpgrade-address-}[`++_authorizeUpgrade()++`] -* {xref-PluginRepo-supportsInterface-bytes4-}[`++supportsInterface(_interfaceId)++`] -* {xref-PluginRepo-MAINTAINER_PERMISSION_ID-bytes32}[`++MAINTAINER_PERMISSION_ID()++`] -* {xref-PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32}[`++UPGRADE_REPO_PERMISSION_ID()++`] -* {xref-PluginRepo-latestRelease-uint8}[`++latestRelease()++`] - -[.contract-subindex-inherited] -.PermissionManager -* {xref-PermissionManager-__PermissionManager_init-address-}[`++__PermissionManager_init(_initialOwner)++`] -* {xref-PermissionManager-grant-address-address-bytes32-}[`++grant(_where, _who, _permissionId)++`] -* {xref-PermissionManager-grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++grantWithCondition(_where, _who, _permissionId, _condition)++`] -* {xref-PermissionManager-revoke-address-address-bytes32-}[`++revoke(_where, _who, _permissionId)++`] -* {xref-PermissionManager-applySingleTargetPermissions-address-struct-PermissionLib-SingleTargetPermission---}[`++applySingleTargetPermissions(_where, items)++`] -* {xref-PermissionManager-applyMultiTargetPermissions-struct-PermissionLib-MultiTargetPermission---}[`++applyMultiTargetPermissions(_items)++`] -* {xref-PermissionManager-isGranted-address-address-bytes32-bytes-}[`++isGranted(_where, _who, _permissionId, _data)++`] -* {xref-PermissionManager-_checkCondition-address-address-address-bytes32-bytes-}[`++_checkCondition(_condition, _where, _who, _permissionId, _data)++`] -* {xref-PermissionManager-_initializePermissionManager-address-}[`++_initializePermissionManager(_initialOwner)++`] -* {xref-PermissionManager-_grant-address-address-bytes32-}[`++_grant(_where, _who, _permissionId)++`] -* {xref-PermissionManager-_grantWithCondition-address-address-bytes32-contract-IPermissionCondition-}[`++_grantWithCondition(_where, _who, _permissionId, _condition)++`] -* {xref-PermissionManager-_revoke-address-address-bytes32-}[`++_revoke(_where, _who, _permissionId)++`] -* {xref-PermissionManager-_auth-bytes32-}[`++_auth(_permissionId)++`] -* {xref-PermissionManager-permissionHash-address-address-bytes32-}[`++permissionHash(_where, _who, _permissionId)++`] -* {xref-PermissionManager-isPermissionRestrictedForAnyAddr-bytes32-}[`++isPermissionRestrictedForAnyAddr(_permissionId)++`] -* {xref-PermissionManager-ROOT_PERMISSION_ID-bytes32}[`++ROOT_PERMISSION_ID()++`] - -[.contract-subindex-inherited] -.ProtocolVersion -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.IPluginRepo - -[.contract-subindex-inherited] -.ERC165Upgradeable - -[.contract-subindex-inherited] -.IERC165Upgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Events --- - -[.contract-subindex-inherited] -.PermissionManager -* {xref-PermissionManager-Granted-bytes32-address-address-address-address-}[`++Granted(permissionId, here, where, who, condition)++`] -* {xref-PermissionManager-Revoked-bytes32-address-address-address-}[`++Revoked(permissionId, here, where, who)++`] - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.IPluginRepo -* {xref-IPluginRepo-VersionCreated-uint8-uint16-address-bytes-}[`++VersionCreated(release, build, pluginSetup, buildMetadata)++`] -* {xref-IPluginRepo-ReleaseMetadataUpdated-uint8-bytes-}[`++ReleaseMetadataUpdated(release, releaseMetadata)++`] - -[.contract-subindex-inherited] -.ERC165Upgradeable - -[.contract-subindex-inherited] -.IERC165Upgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Errors --- - -[.contract-subindex-inherited] -.PermissionManager - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.IPluginRepo - -[.contract-subindex-inherited] -.ERC165Upgradeable - -[.contract-subindex-inherited] -.IERC165Upgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-index] -.Internal Variables --- - -[.contract-subindex-inherited] -.PermissionManager - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - -[.contract-subindex-inherited] -.UUPSUpgradeable - -[.contract-subindex-inherited] -.ERC1967UpgradeUpgradeable - -[.contract-subindex-inherited] -.IERC1967Upgradeable - -[.contract-subindex-inherited] -.IERC1822ProxiableUpgradeable - -[.contract-subindex-inherited] -.IPluginRepo - -[.contract-subindex-inherited] -.ERC165Upgradeable - -[.contract-subindex-inherited] -.IERC165Upgradeable - -[.contract-subindex-inherited] -.Initializable - --- - -[.contract-item] -[[PluginRepo-constructor--]] -==== `[.contract-item-name]#++constructor++#++()++` [.item-kind]#public# - -Used to disallow initializing the implementation contract by an attacker for extra safety. - -[.contract-item] -[[PluginRepo-initialize-address-]] -==== `[.contract-item-name]#++initialize++#++(address initialOwner)++` [.item-kind]#external# - -Initializes the contract by -- initializing the permission manager -- granting the `MAINTAINER_PERMISSION_ID` permission to the initial owner. - -This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). - -[.contract-item] -[[PluginRepo-initializeFrom-uint8-3--bytes-]] -==== `[.contract-item-name]#++initializeFrom++#++(uint8[3] _previousProtocolVersion, bytes _initData)++` [.item-kind]#external# - -Initializes the pluginRepo after an upgrade from a previous protocol version. - -This function is a placeholder until we require reinitialization. - -[.contract-item] -[[PluginRepo-createVersion-uint8-address-bytes-bytes-]] -==== `[.contract-item-name]#++createVersion++#++(uint8 _release, address _pluginSetup, bytes _buildMetadata, bytes _releaseMetadata)++` [.item-kind]#external# - -Creates a new plugin version as the latest build for an existing release number or the first build for a new release number for the provided `PluginSetup` contract address and metadata. - -[.contract-item] -[[PluginRepo-updateReleaseMetadata-uint8-bytes-]] -==== `[.contract-item-name]#++updateReleaseMetadata++#++(uint8 _release, bytes _releaseMetadata)++` [.item-kind]#external# - -Updates the metadata for release with content `@fromHex(_releaseMetadata)`. - -[.contract-item] -[[PluginRepo-getLatestVersion-uint8-]] -==== `[.contract-item-name]#++getLatestVersion++#++(uint8 _release) → struct PluginRepo.Version++` [.item-kind]#public# - -Returns the latest version for a given release number. - -[.contract-item] -[[PluginRepo-getLatestVersion-address-]] -==== `[.contract-item-name]#++getLatestVersion++#++(address _pluginSetup) → struct PluginRepo.Version++` [.item-kind]#public# - -Returns the latest version for a given plugin setup. - -[.contract-item] -[[PluginRepo-getVersion-struct-PluginRepo-Tag-]] -==== `[.contract-item-name]#++getVersion++#++(struct PluginRepo.Tag _tag) → struct PluginRepo.Version++` [.item-kind]#public# - -Returns the version associated with a tag. - -[.contract-item] -[[PluginRepo-getVersion-bytes32-]] -==== `[.contract-item-name]#++getVersion++#++(bytes32 _tagHash) → struct PluginRepo.Version++` [.item-kind]#public# - -Returns the version for a tag hash. - -[.contract-item] -[[PluginRepo-buildCount-uint8-]] -==== `[.contract-item-name]#++buildCount++#++(uint8 _release) → uint256++` [.item-kind]#public# - -Gets the total number of builds for a given release number. - -[.contract-item] -[[PluginRepo-tagHash-struct-PluginRepo-Tag-]] -==== `[.contract-item-name]#++tagHash++#++(struct PluginRepo.Tag _tag) → bytes32++` [.item-kind]#internal# - -The hash of the version tag obtained from the packed, bytes-encoded release and build number. - -[.contract-item] -[[PluginRepo-_authorizeUpgrade-address-]] -==== `[.contract-item-name]#++_authorizeUpgrade++#++(address)++` [.item-kind]#internal# - -Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). - -The caller must have the `UPGRADE_REPO_PERMISSION_ID` permission. - -[.contract-item] -[[PluginRepo-supportsInterface-bytes4-]] -==== `[.contract-item-name]#++supportsInterface++#++(bytes4 _interfaceId) → bool++` [.item-kind]#public# - -Checks if this or the parent contract supports an interface by its ID. - -[.contract-item] -[[PluginRepo-MAINTAINER_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++MAINTAINER_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `createVersion` function. - -[.contract-item] -[[PluginRepo-UPGRADE_REPO_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++UPGRADE_REPO_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `createVersion` function. - -[.contract-item] -[[PluginRepo-latestRelease-uint8]] -==== `[.contract-item-name]#++latestRelease++#++() → uint8++` [.item-kind]#public# - -The ID of the latest release. - -The maximum release number is 255. - -[.contract-item] -[[PluginRepo-VersionHashDoesNotExist-bytes32-]] -==== `[.contract-item-name]#++VersionHashDoesNotExist++#++(bytes32 versionHash)++` [.item-kind]#error# - -Thrown if a version does not exist. - -[.contract-item] -[[PluginRepo-InvalidPluginSetupInterface--]] -==== `[.contract-item-name]#++InvalidPluginSetupInterface++#++()++` [.item-kind]#error# - -Thrown if a plugin setup contract does not inherit from `PluginSetup`. - -[.contract-item] -[[PluginRepo-ReleaseZeroNotAllowed--]] -==== `[.contract-item-name]#++ReleaseZeroNotAllowed++#++()++` [.item-kind]#error# - -Thrown if a release number is zero. - -[.contract-item] -[[PluginRepo-InvalidReleaseIncrement-uint8-uint8-]] -==== `[.contract-item-name]#++InvalidReleaseIncrement++#++(uint8 latestRelease, uint8 newRelease)++` [.item-kind]#error# - -Thrown if a release number is incremented by more than one. - -[.contract-item] -[[PluginRepo-PluginSetupAlreadyInPreviousRelease-uint8-uint16-address-]] -==== `[.contract-item-name]#++PluginSetupAlreadyInPreviousRelease++#++(uint8 release, uint16 build, address pluginSetup)++` [.item-kind]#error# - -Thrown if the same plugin setup contract exists already in a previous releases. - -[.contract-item] -[[PluginRepo-EmptyReleaseMetadata--]] -==== `[.contract-item-name]#++EmptyReleaseMetadata++#++()++` [.item-kind]#error# - -Thrown if the metadata URI is empty. - -[.contract-item] -[[PluginRepo-ReleaseDoesNotExist--]] -==== `[.contract-item-name]#++ReleaseDoesNotExist++#++()++` [.item-kind]#error# - -Thrown if release does not exist. - -[.contract-item] -[[PluginRepo-buildsPerRelease-mapping-uint8----uint16-]] -==== `mapping(uint8 => uint16) [.contract-item-name]#++buildsPerRelease++#` [.item-kind]#internal# - -The mapping between release and build numbers. - -[.contract-item] -[[PluginRepo-versions-mapping-bytes32----struct-PluginRepo-Version-]] -==== `mapping(bytes32 => struct PluginRepo.Version) [.contract-item-name]#++versions++#` [.item-kind]#internal# - -The mapping between the version hash and the corresponding version information. - -[.contract-item] -[[PluginRepo-latestTagHashForPluginSetup-mapping-address----bytes32-]] -==== `mapping(address => bytes32) [.contract-item-name]#++latestTagHashForPluginSetup++#` [.item-kind]#internal# - -The mapping between the plugin setup address and its corresponding version hash. - -:APPLY_INSTALLATION_PERMISSION_ID: pass:normal[xref:#PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32[`++APPLY_INSTALLATION_PERMISSION_ID++`]] -:APPLY_UPDATE_PERMISSION_ID: pass:normal[xref:#PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32[`++APPLY_UPDATE_PERMISSION_ID++`]] -:APPLY_UNINSTALLATION_PERMISSION_ID: pass:normal[xref:#PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32[`++APPLY_UNINSTALLATION_PERMISSION_ID++`]] -:PluginState: pass:normal[xref:#PluginSetupProcessor-PluginState[`++PluginState++`]] -:states: pass:normal[xref:#PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState-[`++states++`]] -:PrepareInstallationParams: pass:normal[xref:#PluginSetupProcessor-PrepareInstallationParams[`++PrepareInstallationParams++`]] -:ApplyInstallationParams: pass:normal[xref:#PluginSetupProcessor-ApplyInstallationParams[`++ApplyInstallationParams++`]] -:PrepareUpdateParams: pass:normal[xref:#PluginSetupProcessor-PrepareUpdateParams[`++PrepareUpdateParams++`]] -:ApplyUpdateParams: pass:normal[xref:#PluginSetupProcessor-ApplyUpdateParams[`++ApplyUpdateParams++`]] -:PrepareUninstallationParams: pass:normal[xref:#PluginSetupProcessor-PrepareUninstallationParams[`++PrepareUninstallationParams++`]] -:ApplyUninstallationParams: pass:normal[xref:#PluginSetupProcessor-ApplyUninstallationParams[`++ApplyUninstallationParams++`]] -:repoRegistry: pass:normal[xref:#PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry[`++repoRegistry++`]] -:SetupApplicationUnauthorized: pass:normal[xref:#PluginSetupProcessor-SetupApplicationUnauthorized-address-address-bytes32-[`++SetupApplicationUnauthorized++`]] -:PluginNonupgradeable: pass:normal[xref:#PluginSetupProcessor-PluginNonupgradeable-address-[`++PluginNonupgradeable++`]] -:PluginProxyUpgradeFailed: pass:normal[xref:#PluginSetupProcessor-PluginProxyUpgradeFailed-address-address-bytes-[`++PluginProxyUpgradeFailed++`]] -:IPluginNotSupported: pass:normal[xref:#PluginSetupProcessor-IPluginNotSupported-address-[`++IPluginNotSupported++`]] -:PluginRepoNonexistent: pass:normal[xref:#PluginSetupProcessor-PluginRepoNonexistent--[`++PluginRepoNonexistent++`]] -:SetupAlreadyPrepared: pass:normal[xref:#PluginSetupProcessor-SetupAlreadyPrepared-bytes32-[`++SetupAlreadyPrepared++`]] -:SetupNotApplicable: pass:normal[xref:#PluginSetupProcessor-SetupNotApplicable-bytes32-[`++SetupNotApplicable++`]] -:InvalidUpdateVersion: pass:normal[xref:#PluginSetupProcessor-InvalidUpdateVersion-struct-PluginRepo-Tag-struct-PluginRepo-Tag-[`++InvalidUpdateVersion++`]] -:PluginAlreadyInstalled: pass:normal[xref:#PluginSetupProcessor-PluginAlreadyInstalled--[`++PluginAlreadyInstalled++`]] -:InvalidAppliedSetupId: pass:normal[xref:#PluginSetupProcessor-InvalidAppliedSetupId-bytes32-bytes32-[`++InvalidAppliedSetupId++`]] -:InstallationPrepared: pass:normal[xref:#PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData-[`++InstallationPrepared++`]] -:InstallationApplied: pass:normal[xref:#PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32-[`++InstallationApplied++`]] -:UpdatePrepared: pass:normal[xref:#PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes-[`++UpdatePrepared++`]] -:UpdateApplied: pass:normal[xref:#PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32-[`++UpdateApplied++`]] -:UninstallationPrepared: pass:normal[xref:#PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission---[`++UninstallationPrepared++`]] -:UninstallationApplied: pass:normal[xref:#PluginSetupProcessor-UninstallationApplied-address-address-bytes32-[`++UninstallationApplied++`]] -:canApply: pass:normal[xref:#PluginSetupProcessor-canApply-address-bytes32-[`++canApply++`]] -:constructor: pass:normal[xref:#PluginSetupProcessor-constructor-contract-PluginRepoRegistry-[`++constructor++`]] -:prepareInstallation: pass:normal[xref:#PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams-[`++prepareInstallation++`]] -:applyInstallation: pass:normal[xref:#PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams-[`++applyInstallation++`]] -:prepareUpdate: pass:normal[xref:#PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams-[`++prepareUpdate++`]] -:applyUpdate: pass:normal[xref:#PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams-[`++applyUpdate++`]] -:prepareUninstallation: pass:normal[xref:#PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams-[`++prepareUninstallation++`]] -:applyUninstallation: pass:normal[xref:#PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams-[`++applyUninstallation++`]] -:validatePreparedSetupId: pass:normal[xref:#PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32-[`++validatePreparedSetupId++`]] - -[.contract] -[[PluginSetupProcessor]] -=== `++PluginSetupProcessor++` link:https://github.com/aragon/osx.git/blob/v1.4.0-rc0/src/framework/plugin/setup/PluginSetupProcessor.sol[{github-icon},role=heading-link] - -This contract is temporarily granted the `ROOT_PERMISSION_ID` permission on the applying DAO and therefore is highly security critical. - -[.contract-index] -.Modifiers --- -* {xref-PluginSetupProcessor-canApply-address-bytes32-}[`++canApply(_dao, _permissionId)++`] - --- - -[.contract-index] -.Functions --- -* {xref-PluginSetupProcessor-constructor-contract-PluginRepoRegistry-}[`++constructor(_repoRegistry)++`] -* {xref-PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams-}[`++prepareInstallation(_dao, _params)++`] -* {xref-PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams-}[`++applyInstallation(_dao, _params)++`] -* {xref-PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams-}[`++prepareUpdate(_dao, _params)++`] -* {xref-PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams-}[`++applyUpdate(_dao, _params)++`] -* {xref-PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams-}[`++prepareUninstallation(_dao, _params)++`] -* {xref-PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams-}[`++applyUninstallation(_dao, _params)++`] -* {xref-PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32-}[`++validatePreparedSetupId(pluginInstallationId, preparedSetupId)++`] -* {xref-PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32}[`++APPLY_INSTALLATION_PERMISSION_ID()++`] -* {xref-PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32}[`++APPLY_UPDATE_PERMISSION_ID()++`] -* {xref-PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32}[`++APPLY_UNINSTALLATION_PERMISSION_ID()++`] -* {xref-PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState-}[`++states()++`] -* {xref-PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry}[`++repoRegistry()++`] - -[.contract-subindex-inherited] -.ProtocolVersion -* link:https://github.com/aragon/osx-commons/tree/main/contracts/src/utils/versioning/ProtocolVersion.sol[protocolVersion] - -[.contract-subindex-inherited] -.IProtocolVersion - --- - -[.contract-index] -.Events --- -* {xref-PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData-}[`++InstallationPrepared(sender, dao, preparedSetupId, pluginSetupRepo, versionTag, data, plugin, preparedSetupData)++`] -* {xref-PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32-}[`++InstallationApplied(dao, plugin, preparedSetupId, appliedSetupId)++`] -* {xref-PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes-}[`++UpdatePrepared(sender, dao, preparedSetupId, pluginSetupRepo, versionTag, setupPayload, preparedSetupData, initData)++`] -* {xref-PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32-}[`++UpdateApplied(dao, plugin, preparedSetupId, appliedSetupId)++`] -* {xref-PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission---}[`++UninstallationPrepared(sender, dao, preparedSetupId, pluginSetupRepo, versionTag, setupPayload, permissions)++`] -* {xref-PluginSetupProcessor-UninstallationApplied-address-address-bytes32-}[`++UninstallationApplied(dao, plugin, preparedSetupId)++`] - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - --- - -[.contract-index] -.Errors --- - -[.contract-subindex-inherited] -.ProtocolVersion - -[.contract-subindex-inherited] -.IProtocolVersion - --- - -[.contract-item] -[[PluginSetupProcessor-canApply-address-bytes32-]] -==== `[.contract-item-name]#++canApply++#++(address _dao, bytes32 _permissionId)++` [.item-kind]#modifier# - -A modifier to check if a caller has the permission to apply a prepared setup. - -[.contract-item] -[[PluginSetupProcessor-constructor-contract-PluginRepoRegistry-]] -==== `[.contract-item-name]#++constructor++#++(contract PluginRepoRegistry _repoRegistry)++` [.item-kind]#public# - -Constructs the plugin setup processor by setting the associated plugin repo registry. - -[.contract-item] -[[PluginSetupProcessor-prepareInstallation-address-struct-PluginSetupProcessor-PrepareInstallationParams-]] -==== `[.contract-item-name]#++prepareInstallation++#++(address _dao, struct PluginSetupProcessor.PrepareInstallationParams _params) → address plugin, struct IPluginSetup.PreparedSetupData preparedSetupData++` [.item-kind]#external# - -Prepares the installation of a plugin. - -[.contract-item] -[[PluginSetupProcessor-applyInstallation-address-struct-PluginSetupProcessor-ApplyInstallationParams-]] -==== `[.contract-item-name]#++applyInstallation++#++(address _dao, struct PluginSetupProcessor.ApplyInstallationParams _params)++` [.item-kind]#external# - -Applies the permissions of a prepared installation to a DAO. - -[.contract-item] -[[PluginSetupProcessor-prepareUpdate-address-struct-PluginSetupProcessor-PrepareUpdateParams-]] -==== `[.contract-item-name]#++prepareUpdate++#++(address _dao, struct PluginSetupProcessor.PrepareUpdateParams _params) → bytes initData, struct IPluginSetup.PreparedSetupData preparedSetupData++` [.item-kind]#external# - -Prepares the update of an UUPS upgradeable plugin. - -The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happened) on which the update is prepared for. - -[.contract-item] -[[PluginSetupProcessor-applyUpdate-address-struct-PluginSetupProcessor-ApplyUpdateParams-]] -==== `[.contract-item-name]#++applyUpdate++#++(address _dao, struct PluginSetupProcessor.ApplyUpdateParams _params)++` [.item-kind]#external# - -Applies the permissions of a prepared update of an UUPS upgradeable proxy contract to a DAO. - -[.contract-item] -[[PluginSetupProcessor-prepareUninstallation-address-struct-PluginSetupProcessor-PrepareUninstallationParams-]] -==== `[.contract-item-name]#++prepareUninstallation++#++(address _dao, struct PluginSetupProcessor.PrepareUninstallationParams _params) → struct PermissionLib.MultiTargetPermission[] permissions++` [.item-kind]#external# - -Prepares the uninstallation of a plugin. - -The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happened) on which the uninstallation was prepared for. - -[.contract-item] -[[PluginSetupProcessor-applyUninstallation-address-struct-PluginSetupProcessor-ApplyUninstallationParams-]] -==== `[.contract-item-name]#++applyUninstallation++#++(address _dao, struct PluginSetupProcessor.ApplyUninstallationParams _params)++` [.item-kind]#external# - -Applies the permissions of a prepared uninstallation to a DAO. - -The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happened) on which the uninstallation was prepared for. - -[.contract-item] -[[PluginSetupProcessor-validatePreparedSetupId-bytes32-bytes32-]] -==== `[.contract-item-name]#++validatePreparedSetupId++#++(bytes32 pluginInstallationId, bytes32 preparedSetupId)++` [.item-kind]#public# - -Validates that a setup ID can be applied for `applyInstallation`, `applyUpdate`, or `applyUninstallation`. - -If the block number stored in `states[pluginInstallationId].blockNumber` exceeds the one stored in `pluginState.preparedSetupIdToBlockNumber[preparedSetupId]`, the prepared setup with `preparedSetupId` is outdated and not applicable anymore. - -[.contract-item] -[[PluginSetupProcessor-APPLY_INSTALLATION_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++APPLY_INSTALLATION_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `applyInstallation` function. - -[.contract-item] -[[PluginSetupProcessor-APPLY_UPDATE_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++APPLY_UPDATE_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `applyUpdate` function. - -[.contract-item] -[[PluginSetupProcessor-APPLY_UNINSTALLATION_PERMISSION_ID-bytes32]] -==== `[.contract-item-name]#++APPLY_UNINSTALLATION_PERMISSION_ID++#++() → bytes32++` [.item-kind]#public# - -The ID of the permission required to call the `applyUninstallation` function. - -[.contract-item] -[[PluginSetupProcessor-states-mapping-bytes32----struct-PluginSetupProcessor-PluginState-]] -==== `[.contract-item-name]#++states++#++() → mapping(bytes32 => struct PluginSetupProcessor.PluginState)++` [.item-kind]#public# - -A mapping between the plugin installation ID (obtained from the DAO and plugin address) and the plugin state information. - -This variable is public on purpose to allow future versions to access and migrate the storage. - -[.contract-item] -[[PluginSetupProcessor-repoRegistry-contract-PluginRepoRegistry]] -==== `[.contract-item-name]#++repoRegistry++#++() → contract PluginRepoRegistry++` [.item-kind]#public# - -The plugin repo registry listing the `PluginRepo` contracts versioning the `PluginSetup` contracts. - -[.contract-item] -[[PluginSetupProcessor-InstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-bytes-address-struct-IPluginSetup-PreparedSetupData-]] -==== `[.contract-item-name]#++InstallationPrepared++#++(address indexed sender, address indexed dao, bytes32 preparedSetupId, contract PluginRepo indexed pluginSetupRepo, struct PluginRepo.Tag versionTag, bytes data, address plugin, struct IPluginSetup.PreparedSetupData preparedSetupData)++` [.item-kind]#event# - -Emitted with a prepared plugin installation to store data relevant for the application step. - -[.contract-item] -[[PluginSetupProcessor-InstallationApplied-address-address-bytes32-bytes32-]] -==== `[.contract-item-name]#++InstallationApplied++#++(address indexed dao, address indexed plugin, bytes32 preparedSetupId, bytes32 appliedSetupId)++` [.item-kind]#event# - -Emitted after a plugin installation was applied. - -[.contract-item] -[[PluginSetupProcessor-UpdatePrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-IPluginSetup-PreparedSetupData-bytes-]] -==== `[.contract-item-name]#++UpdatePrepared++#++(address indexed sender, address indexed dao, bytes32 preparedSetupId, contract PluginRepo indexed pluginSetupRepo, struct PluginRepo.Tag versionTag, struct IPluginSetup.SetupPayload setupPayload, struct IPluginSetup.PreparedSetupData preparedSetupData, bytes initData)++` [.item-kind]#event# - -Emitted with a prepared plugin update to store data relevant for the application step. - -[.contract-item] -[[PluginSetupProcessor-UpdateApplied-address-address-bytes32-bytes32-]] -==== `[.contract-item-name]#++UpdateApplied++#++(address indexed dao, address indexed plugin, bytes32 preparedSetupId, bytes32 appliedSetupId)++` [.item-kind]#event# - -Emitted after a plugin update was applied. - -[.contract-item] -[[PluginSetupProcessor-UninstallationPrepared-address-address-bytes32-contract-PluginRepo-struct-PluginRepo-Tag-struct-IPluginSetup-SetupPayload-struct-PermissionLib-MultiTargetPermission---]] -==== `[.contract-item-name]#++UninstallationPrepared++#++(address indexed sender, address indexed dao, bytes32 preparedSetupId, contract PluginRepo indexed pluginSetupRepo, struct PluginRepo.Tag versionTag, struct IPluginSetup.SetupPayload setupPayload, struct PermissionLib.MultiTargetPermission[] permissions)++` [.item-kind]#event# - -Emitted with a prepared plugin uninstallation to store data relevant for the application step. - -[.contract-item] -[[PluginSetupProcessor-UninstallationApplied-address-address-bytes32-]] -==== `[.contract-item-name]#++UninstallationApplied++#++(address indexed dao, address indexed plugin, bytes32 preparedSetupId)++` [.item-kind]#event# - -Emitted after a plugin installation was applied. - -[.contract-item] -[[PluginSetupProcessor-SetupApplicationUnauthorized-address-address-bytes32-]] -==== `[.contract-item-name]#++SetupApplicationUnauthorized++#++(address dao, address caller, bytes32 permissionId)++` [.item-kind]#error# - -Thrown if a setup is unauthorized and cannot be applied because of a missing permission of the associated DAO. - -This is thrown if the `APPLY_INSTALLATION_PERMISSION_ID`, `APPLY_UPDATE_PERMISSION_ID`, or APPLY_UNINSTALLATION_PERMISSION_ID is missing. - -[.contract-item] -[[PluginSetupProcessor-PluginNonupgradeable-address-]] -==== `[.contract-item-name]#++PluginNonupgradeable++#++(address plugin)++` [.item-kind]#error# - -Thrown if a plugin is not upgradeable. - -[.contract-item] -[[PluginSetupProcessor-PluginProxyUpgradeFailed-address-address-bytes-]] -==== `[.contract-item-name]#++PluginProxyUpgradeFailed++#++(address proxy, address implementation, bytes initData)++` [.item-kind]#error# - -Thrown if the upgrade of an `UUPSUpgradeable` proxy contract (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)) failed. - -[.contract-item] -[[PluginSetupProcessor-IPluginNotSupported-address-]] -==== `[.contract-item-name]#++IPluginNotSupported++#++(address plugin)++` [.item-kind]#error# - -Thrown if a contract does not support the `IPlugin` interface. - -[.contract-item] -[[PluginSetupProcessor-PluginRepoNonexistent--]] -==== `[.contract-item-name]#++PluginRepoNonexistent++#++()++` [.item-kind]#error# - -Thrown if a plugin repository does not exist on the plugin repo registry. - -[.contract-item] -[[PluginSetupProcessor-SetupAlreadyPrepared-bytes32-]] -==== `[.contract-item-name]#++SetupAlreadyPrepared++#++(bytes32 preparedSetupId)++` [.item-kind]#error# - -Thrown if a plugin setup was already prepared indicated by the prepared setup ID. - -[.contract-item] -[[PluginSetupProcessor-SetupNotApplicable-bytes32-]] -==== `[.contract-item-name]#++SetupNotApplicable++#++(bytes32 preparedSetupId)++` [.item-kind]#error# - -Thrown if a prepared setup ID is not eligible to be applied. This can happen if another setup has been already applied or if the setup wasn't prepared in the first place. - -[.contract-item] -[[PluginSetupProcessor-InvalidUpdateVersion-struct-PluginRepo-Tag-struct-PluginRepo-Tag-]] -==== `[.contract-item-name]#++InvalidUpdateVersion++#++(struct PluginRepo.Tag currentVersionTag, struct PluginRepo.Tag newVersionTag)++` [.item-kind]#error# - -Thrown if the update version is invalid. - -[.contract-item] -[[PluginSetupProcessor-PluginAlreadyInstalled--]] -==== `[.contract-item-name]#++PluginAlreadyInstalled++#++()++` [.item-kind]#error# - -Thrown if plugin is already installed and one tries to prepare or apply install on it. - -[.contract-item] -[[PluginSetupProcessor-InvalidAppliedSetupId-bytes32-bytes32-]] -==== `[.contract-item-name]#++InvalidAppliedSetupId++#++(bytes32 currentAppliedSetupId, bytes32 appliedSetupId)++` [.item-kind]#error# - -Thrown if the applied setup ID resulting from the supplied setup payload does not match with the current applied setup ID. - diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index f54029303..10568bd39 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -191,7 +191,7 @@ const config: HardhatUserConfig = { artifacts: './artifacts', deploy: './deploy', }, - docgen: require('./docs/config.js'), + docgen: process.env.DOCS ? require('./docs/config.js') : undefined, mocha: { timeout: 90_000, // 90 seconds // increase the timeout for subdomain validation tests }, diff --git a/packages/contracts/package.json b/packages/contracts/package.json index b2603298b..29338d2a8 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -28,12 +28,12 @@ "dev": "yarn hardhat node --hostname 0.0.0.0", "prepublishOnly": "yarn build && yarn build:npm", "docgen": "hardhat docgen", - "docs": "scripts/prepare-docs.sh", + "docs": "DOCS=true scripts/prepare-docs.sh", "clean": "rm -rf artifacts cache deployments typechain" }, "repository": { "type": "git", - "url": "https://github.com/aragon/osx.git" + "url": "https://github.com/aragon/osx" }, "author": "", "license": "AGPL-3.0-or-later", diff --git a/packages/contracts/src/core/README.adoc b/packages/contracts/src/core/README.adoc new file mode 100644 index 000000000..abd361dce --- /dev/null +++ b/packages/contracts/src/core/README.adoc @@ -0,0 +1,13 @@ += OSX + +This is the reference guide of the link:https://github.com/aragon/osx[osx contracts] package. + +== Core + +{{DAO}} + +{{IDAO}} + +{{PermissionManager}} + +{{CallbackHandler}} \ No newline at end of file diff --git a/packages/contracts/src/framework/README.adoc b/packages/contracts/src/framework/README.adoc new file mode 100644 index 000000000..f6229a795 --- /dev/null +++ b/packages/contracts/src/framework/README.adoc @@ -0,0 +1,19 @@ +== Framework API + +=== Factories + +{{DAOFactory}} + +{{PluginRepoFactory}} + +=== Registries + +{{DAORegistry}} + +{{PluginRepoRegistry}} + +=== Framework + +{{PluginRepo}} + +{{PluginSetupProcessor}} \ No newline at end of file