Main DAO

The Main DAO will be responsible to execute the most important decisions for OpenWork's operations, security and growth like Token Management, Voting on Key Proposals, Staking and initiating Upgrades on all chains.

To stay within the limit of Ethereum Contract size-limit, we have split the contract into 3 files:

  1. The OpenworkDAO contract - This is the contract which will handle all the logic described below

  2. The OpenWork timelock - This contract will be used delay key functions like the un-staking of tokens

  3. The Openwork Governor - This will hold logic for the OpenZeppelin Governor pattern to be used by the OpenworkDAO contract

Description
Implementation

The treasury would manage both OpenWork tokens and OpenWork’s funds in other crypto assets [ERC20, mainly should be USDC and USDT].

Smart Contracts by default can accept all ERC-20 tokens. So no special implementation needed here.

1B tokens are minted all at once on the Ethereum Mainnet and distributed according to the Rewards Table.

Tokens will be minted using the mint() function. This function can be only called by the deployer & Governance. Governance means this function is called on passing of a proposal(described later on in this doc). There is no hard-coded division for the pools described in description. DAO has to make sure allocations are followed. Later DAO can decide to enforce the tokenomics at the code level.

Staking will be done on Ethereum through MainDAO. Other chains can access this info through a Bridge.

Only this contract will have the Stake function and will communicate this data to other chains through bridges. Other chains can call getStake(member_address) to get the stake of a person or getAllStakers() to get a list of all stakers with their stakes.

Any token holder with at least 100k staked can join the DAO and vote on proposal.

There are three types of people who can stake and participate in governance [DAO or Athena].

  1. People who have Earned Tokens

  2. People who have Bought tokens

Struct: DAOmember {member_address, staked_amount, period, unlockDate} Function: joinDAO(stakeAmount, stake_period) { has 100k tokens? add address to the list of DAOmembers add staked amount and period set Unlock date

} Note: Team & Earned tokens are locked by default until conditions for their unstaking are met.

Tokens can be staked for 1,2,3 years. Only the tokens which are locked or staked by an individual will count when voting. [1,2,3X respective governance power is given].

voteOnProposal(yes/no) { check if caller has atleast 100k staked tokens, earned tokens or team tokens Voting power = Staked Tokens X Period of staking add votes to proposal }

Unstaked/Redeemed Tokens can be gotten back after 14 days from when the function to unstake them is called.

unstake(amount) { check is stake exists check if staking period is over release tokens with a timelock of 14 days } See Unlocking/Unstaking Logic to see how to redeem Team and Earned Tokens

Remove stake of member as a penalty.

This will done through a proposal

Initiating Proposals: Members with at least 1M of OpenWork tokens staked are eligible to submit proposals, ensuring active participants with significant stake can influence key decisions.

Any DAO member with >1M tokens can call the propose() function to initiate a proposal. Here's how a proposal can be called: Field 1 : Targets : this is the list of contract addresses to be called Field 2 : Value : this is the amount to be transferred Field 3 : Call Data : this is the encoded signature of the function that needs to be called after the proposal is passed. Field 4 : description : a small description of the proposal

Voting Threshold for Approval: For a proposal to pass, it requires an 80% majority in favour, with at least 20% of the total token supply participating in the vote.

This is defined as the quorum value which can be changed later using a proposal.

[This should just be at least possible using upgrades] Using OpenWork itself to build and promote OpenWork. The OpenWork treasury should be usable so that it can create and manage jobs on OpenWork. For example, let's say it’s a community management activity, it should be all done through OpenWork’s work protocols. Ability for OpenWork itself to either instantly or at some point in the future be rebuilt using OpenWork’s protocols.

Proposals can be used to do this.

Delegation of votes to other addresses.

there's a default delegate() function in the governor pattern which needs to be declared.

Main DAO contract should have the ability to authorise

  1. Upgrades on other chains

  2. Stake of DAO members

  3. Is someone a DAO member or not

Other chains can call functions like - getStake(member_address), getAllDAOmembers() and isDAOmember() - to get info about DAO members and their stake. For upgrades on other chains, this contract will have a function to call the upgrade function on any other chain. Only Governance can call the upgradeInterchain() function with the following params: 1. Chain ID of target chain, 2.contract address of the proxy contract, 3.Contract address of the new implementation address.

Earned Tokens Must be Vested/Staked in a Safe Way where the DAO can remove a member’s tokens if required due to malicious action, or not fulfilling promises.

The Earned tokens are just registered in a ledger called Earned Tokens. Earner can only claim them after 1 year and once they have done the necessary governance actions. Governance Actions are also recorded in a similar ledger called Governance Actions which is incremented everytime someone does a governance action. Governance Action { address: total_actions }

Earners tokens are auto-staked as soon as they are earned. After this, the earner should be able to do everything a normal staker can do, based on the earned/staked amount.

Earned tokens are by default considered staked so every time a function checks if someone has staked tokens, on failure of this condition, they should also check if the caller has any Earned tokens.

Should reference all OpenWork contracts on all chains.

A struct called originalContract will hold the latest addresses of the official contract in the OpenWork system on all chains. There should also be a getter function to get the addresses of each of the official contracts in the system on all chains.

All contracts (except Token) will be upgrade-able using the OpenZeppelin UUPS upgrade pattern. All upgrades on chains will be authorised through a DAO proposal. CCIP will be used to trigger upgrades on non-Ethereum contracts.

All contracts(except Token) will have a proxy contract which is the constant address which doesn't change and an Implementation contract which holds the logic. The Implementation Contract and thereby contract logic can be upgraded using the Upgrade function on the proxy. Upgrade function on all proxy contracts will be authorised to be used by the Main DAO contract only so that only DAO can initiate upgrades.

The rules of the majority vote system itself must be upgradable. For now, for any smart contract upgrade it can start with something like 80% of votes needing to be in favour with a minimum 20% of the total token supply voting for a smart contract upgrade to take place.

This can be done through a proposal to upgrade the DAO contract or just call the function to update the quorum settings.

In sync with the upgrading step above, there should be the ability to upgrade for Future Rules: The DAO includes a framework for updating and customising voting rules and participation thresholds for treasury proposals, allowing governance practices to evolve based on community needs and experiences. Future updates could allow flexibility such that there are brackets for proposals, time based release of funds where community can revoke if progress isn’t seen. Decentraland’s DAO has this and it works well.

Voting Rules should be update-able

updateVotingRules()

Minimum staking rules should be update-able

updateMinStaking()

Last updated