--- ###### tags: `v3` --- # V3 Proposal Specification Odds and Ends ## Submitting Proposal ### Base args ```sol function submitProposal( bytes calldata proposalData, uint32 expiration, uint256 baalGas, string calldata details ) ``` **proposalData** - See below for a details on some action data for a few proposal types - can reuse encoding helpers - encodeFunction - encodeMulti - might just be in v2 still? **expiration** - Timestamp (unix epoch) after which the proposal can't be processed and is skipped. - Time and date converted to seconds **baalGas** - Estimated gas needed to process all the actions in the proposal - if set to 0 the processProposal function will let any amount of gas provided through and try to execute the actions - could lead to failure and a locked proposal - Our app will need to make a call to the gnosis api to get the estimate - we should make a helper function in the dao-data or common-utilities library to help with this - safe estimate api: https://safe-transaction.goerli.gnosis.io/v1/safes/{address}/multisig-transactions/estimations/ - Address === the baal's safe address - Method: POST - body: ```json { "to": <gnosisMultisendLibrary address>, "value": 0, "data": <Proposal Data>, "operation": 1 } ``` - We can store the multisend address for each chain in one of our keychains - Data is the same encoded proposalData we send with the proposal - Once we get the estmate back we are going to bump it by **30%** to hedge it **details** - json with standard format - the subgraph is parsing and storing some fields on the entity itself - schema: ```json { "title": '20 Share Giveaway', "description": 'Give 20 share to some random address', "contentURI": 'https://www.twistedchickentenders.com/', "contentURIType": 'link', "proposalType": <some proposal type>, } ``` content types could be any number of things we can handle in the front end - link - ipfsHash - markdown - encoded something proposalType - we should keep a master list of proposal types somewhere and agree to them somehow. - this ought to become a free-for-all with proposal coming in outside daohaus ui ***TODO: Write a json schema for the details*** ### Issue or capture shares/loot actions - 1 to many actions - - can send an array of addresses to mint/burn for many at once - a combo of these would work for 'promotion' - also used for requesting tokens without tribute contract: baal function: mintShares/mintLoot args: -address[] calldata to -uint256[] calldata amount function: burnShares/burnLoot args: -address[] calldata from -uint256[] calldata amount ### ProposalData: Add Shaman or change permissions - also takes and array of addresses and perms contract: baal function: setShamans args: - address[] calldata _shamans, - uint256[] calldata _permissions ### ProposalData: Shares/loot transferability contract: baal function: setAdminConfig args: - bool pauseShares - bool pauseLoot ### ProposalData: Change governance settings contract: baal function: setGovernanceConfig args: - uint32 voting - uint32 grace - uint256 newOffering - uint256 quorum - uint256 sponsor - uint256 minRetention ### Tribute proposal action - there is one of these contracts per network - this is not done with the above generic proposal args - no action data to encode! - just a direct transaction to the minion - sender of this proposal will become the tributor and recieve tokens - they must approve the tirbuteMinion to spend thier tokens before proposal processing contract: tributeMinion function: submitTributeProposal args: - Baal baal, - address token, - uint256 amount, - uint256 shares, - uint256 loot, - uint32 expiration, - string memory details ### ProposalData: Transfer tokens actions contract: erc20 function: transfer args: - address to - unit256 amount ## Update Metadata transaction - Same poster call we are used to - direct transaction to the poster contract from the member contract: poster function: post args: - tag - content ## Executing proposals We will need to add a little extra step to the processProposal transaction to account for the gas estimation on the proposal. - estimate will be in the proposal data from the sdk - we can add a 'gasLimit' option the the transaction call with web3 or ethers.js ```js await baal.processProposal(1, proposal.data, { gasLimit: 10000000 }) ``` ## Proposal filtering **Active** - not cancelled - not expired - not failedProcessing - not processed - - not expired maybe: ```js where: { cancelled: false, expired: false, failedProcessing: false, processed: false, expiration: '0' OR expiration_gt: `${expirationTime}`, } ``` also need to see if it's NOT expired: - expiration = 0 OR expiration < now + graceDuration + votingDuration - got a damn OR in there **Action Needed** - needs sponsoring - in voting - and user hasn't voted on it - in grace - needs processing This is a hell of a lot of ORs **Others** We have helper functions to give us the queries for the following: - Unsponsored - In voting - Ready to process - Passed - Failed - Failed processing - Cancelled - Expired - All https://github.com/HausDAO/daohaus-monorepo/blob/develop/libs/dao-data/src/utils/proposalFilters.ts