# DoinGud DAO TechSpec
DoingGud DAO is meant to act as a main organisational mechanism behind DoinGud project. It is meant to manage and organise DuingGud financial streams and funding allocation. DoingGud DAO is going to consist of several elements, including maain MetaDAO, Guild DAO, tokens and staking mechanisms, etc.. (add things here)
We propose to implement parts of DoingGud DAO in stages.
First stage will include implementation of basic tokenomics primitivs such as $AMOR, $dAMOR tokens and Staking contract.
Second stage will include the implementation of MetaDAO that acts as a main mechanism of funds management as well as guilds creation.
Third stage will include the development of Guild and guild related mechanics.

## First stage
### Tokens
#### Tokens Factory
The Tokens factory creates all token contracts specified below for each specific guild and AMOR/dAMOR tokens.
Important functions are:
- `deployAMOR(string memory guild, string memory symbol)` deploys guild token with provided guild name and token symbol.
- `deployDAMOR(address amor)` deploys guild governance token .
- `deployFXtoken(address controller)` deploys FXAMORxGuild token, for specific GuildController and amor token.
#### AMOR
The AMOR token is a standard ERC20 token used in MetaDAO for liquidity. It entails minting rights for the DoinGud multisig. AMOR should be implemented as a simple token with a predefined supply. Each token transfer is taxed (to the MetaDAO and also distributed between all guilds), but by default tax is 0. The maximum taxation should be 5%. The tax from AMOR transfers is distributed between MetaDAO and all of the guilds.
Important functions:
- `transfer(address to, uint256 amount)` - this function call get taxed based on the defined tax percentage. Afterwards contract calls MetaDAO controller to distribute the fees propperly between MetaDAO and all of the Guilds.
- `setTaxRate(uint256 newRate)` - this function call sets tax percentage for the AMOR Token. It is limited up to 50% with 0.1 step.
#### AMORxGuild Curve
It can also be used to exchange with AMORxGuild token. AMOR token is a standard ERC20 token. AMORxGuild is received with the help of the quadratic Curve. The more AMOR tokens are locked in the Curve, the less AMORxGuild will be received from the Curve from the stake. The relationship will be like this: $X$ AMOR tokens - $\sqrt X$ AMORxGuild.
The Curve contract is also an ERC20, but it also should have two special functions:
- `stake(uint256 amount)`. Stake function receives some amount of AMOR tokens. Based on this amount curve is minting some amount of tokens. Total supply of AMORxGuild tokens is regulated with this invariant:
$$I(S,R)=\frac{S^2}{R}$$
Where $I(S,R)$ is a definition of an invariant, which is equal to some constant coefficient, for example $I(S,R) = 1$. $S$ is a token supply of AMORxGuild. $R$ is an amount of staked AMOR tokens. So basically formula with $I(S,R)=1$ means that if we want to have $N$ tokens in supply we need to have $N^2$ tokens staked. From the formula above we can derive:
1. $S^2 = I(S,R) R$
2. $S^2 = R$
3. $S = \sqrt{R}$
When we stake AMOR tokens, it becomes easy to calculate the amount of produced AMORxGuild tokens--this is basically a defined integral. For example, for $I(S,R)=1$ and we have $n$ tokens already staked(which means we have $\sqrt{n}$ tokens minted).
We're going to stake $k$ tokens. The amount of minted tokens is calculated using this formula:
$$N_{minted} = (\sqrt{(n+k)} - \sqrt{n})$$
Stake function is getting taxed up to 20%, tax goes as a donation. This function call increases the weight of the guild inside of the MetaDAO controller by the number of staked tokens.
- `withdraw(uint256 amount)`. Withdraw function receives some amount of AMORxGuild token, burns it and withdraws a corresponding amount of AMOR token. The formula for amount of withdrawn AMOR tokens looks like this: $$N_{withdrawn} = ({TotalSupply}^2 - {(TotalSupply-amount)}^2)$$ Where $TotalSupply$ is an amount of AMORxGuild tokens minted, and $amount$ - amount of burned AMORxGuild tokens.
This function call decreases the weight of the guild inside of the MetaDAO controller by the number of withdrawn tokens.
- `setTaxRate(uint256 newRate)` - this function call sets tax percentage for the AMORxGuild Token. It is limited up to 20% with 0.1 step.
#### dAMOR Token (dAMORxGuild)
dAMOR token is non-transferrable ERC20 governance token for MetaDAO which is used for delegations and voting. dAMOR is received by staking AMOR token at the 1:1 rate. dAMORxGuild is a governance token for a specific guild. It is obtained in 1:1 rate based on the AMORxGuild token. This token is non-transferrable.
Important functions:
- `stake(uint256 amount, uint256 time)` This function allows msg.sender to stake amount of AMORxGuild tokens, which will mint them the amount of dAMORxGuild tokens. The tokens are staked for the time, where $1\ week \leq time \leq 1\ year$. The more time passes, the more tokens will be given to the user. The simplest way to distribute tokens is as such:
* 1 week - 7/365 of amount staked
* 2 weeks - 14/365 of amount staked ...
* 1 year - 365/365 of amount staked
Stake happens with a modifier, which is equal to x2. So if user have staked 100 AMOR tokens for a year, he will receive 200 dAMOR tokens.
- `withdraw()` After the end of staking time user can withdraw their `AMORxGuild` tokens. This function will burn `dAMORxGuild` tokens of user and will return a corresponding amount of `AMORxGuild`. For example if the user staked tokens for 2 weeks, and possessed 100 `dAMORxGuild` then they receive $N_{AMOR} = \frac{N_{dAMOR} *\ 1\ Year}{StakeTime}$. Where $N_{dAMOR}$ is the amount of owned dAMOR tokens and $StakeTime$ is a time for which AMOR tokens were staked.
- `delegate(address account)` delegates voting power of the msg.sender to another specific address.
- `undelegate(address account)` undelegates voting power of the msg.sender from another specific address.
#### FXAMORxGuild Token (REP)
FXAMORxGuild token is a token used to represent the impact. This is a non-transferrable standard ERC20 token. It has mint and burn functions, where mint is can be called by GuildController, which receives a donation from a user, and afterwards 20% of the donation is getting reimbursed with FXAMORxGuild token. FXAMORxGuild can be used to support some report, which will result in burning of those FXAMORxGuild tokens.
Important supported functions:
- `stake(address account, uint256 amount) OnlyOwner` where owner is GuildController contract. This contract receives ERC20 AMORxGuild tokens, which are getting locked and generate FXAMORxGuild tokens in return. Tokens are minted 1:1.
- `burn(address account, uint256 amount) OnlyOwner` - function burns FXAMORxGuild tokens if they are being used for voting. When this tokens are burned, staked AMORxGuild is being transfered to the controller(contract that has a voting function)
- `delegate(address account)` - function that allows some external account to vote with your FXAMORxGuild tokens
This contract also shouldn't have `transfer` and `transferFrom` functions implementation.
## Second stage
### MetaDAO Controller.
Controller contract controls the all of the deployed contracts of the MetaDAO. It mints FXAMOR tokens, disperses the flows of donations to the different pools both for specific Guilds. It is also responsible for deploying another guilds using factory contracts. MetaDAO contract is owned by DoinGud, and is a very important part of managing guilds. The difference between MetaDAO Controller and Guild controller, is that MetaDAO controller can create guilds, distribute funds between guilds(from the fees) and doesn't have a reputation system.
Important variables:
- `guilds address []` Array of guild addresses, guild id is an index of the guild in the array.
- `uint256 guildsTotalWeight` - value that represents the amount of all AMOR tokens staked in specific guilds.
- `guildDistribution uint256 []` Array guilds token amounts they can claim.
- `mapping(bytes32 => Index) public indexes` Mapping of all of the indexes in the guild(Set of guild weights).
It has following important functions:
- `donate(uint256 amount, address token, uint256 index)` - function that allows to donate AMOR tokens to the MetaDAO. It automatically distributes tokens between all of the guilds in which are supported by the MetaDAO based on the id of the provided index(which is a set of the weights).
- `allocateByIndex(address token, uint256 amount, uint256 index)` - function gets an amount of AMOR tokens, which gets staked in the Controller contract, and calculates the distribution of the token between the guilds. It iterates through the `guildDistribution` array, and calculates the amount of distribution based on the this calculation: $$N_{i_{distr}} = \frac{indexTotalWeight}{indexWeight(i)}\ amount$$ Where $N_{i_{distr}}$ is an amount, with which `guildDistribution[i]` is going to be increased(the guild's share). This amount is equal to the rate of the guild weight, comparing to the all guilds weight, multiplied by the distributed amount.
- `claimToken(address token)` - this function claims AMOR tokens for a specific guild(needs to be called from it), then it swaps AMOR with AMORxGuild and donates those funds to the guild organisational pool.
- `createGuild(address realityModule, address initialGuardian, string memory name, string memory tokenSymbol) onlyOwner` - this function calls factory contracts to create guild Controller, and guild tokens. Guild name and tokenSymbol base are provided as a two strings.
- `distributeFees()` - this function is needed to distribute the fees obtained from the AMOR transfers between the guilds and DoinGud itself.
- `addIndex(bytes[] calldata weights)` - this function allows to add the custom index to set the donation distribution between the guilds.
### GuildFactory
GuildFactory deploys tokens, pools and controller contract, and connects them together into functioning guild.
Important function is:
- `deployGuild(address reality, address initialGuardian, string memory _name, string memory _symbol)`, which creates a Controller contract, and calls tokenFactory, which creates AMORxGuild token contract, dAMORxGuild token and FXAmorxGuild with Guild exchanged with a token Symbol.
### GuildController contract
Controller contract controls the all of the deployed contracts of the guild. It mints FXAMOR tokens, disperses the flows of donations to the different pools both for specific Guilds.
Important variables:
- `reportsWeight int256[]` - this is an array, which describes the amount of the weight of each report.(So the reports will later receive payments based on this weight)
- `votes mapping(uint proposal => mapping(address voter => int256 vote))`
- `voters mapping(uint proposal => address [] voters)`
- `reportsVoting`
Important functions:
- `donate(uint256 amount)` - function that allows to donate AMORxGuild tokens to the Guild. It automatically distributes tokens between Impact and project polls(which are both multisigs and governed by the owners of dAMOR) in the 80%-20% distribution. 10% of the tokens in the impact pool are getting staked in the FXAMORxGuild tokens, which are going to be owned by the user.
How does timing for reports works?
- `addReport()` - function which adds another element to the reportsWeight, with weight 0, and starts voting on it.
- `voteForReport(uint256 id, uint256 amount, bool sign)` - function burns the `amount` of FXTokens, and changes a report weight, based on a sign provided. It also sets a vote info for a specific voter.
- `startVoting(uint256[] reportIds) onlyOwner`
- `finalizeVoting() onlyOwner` - function distributes funds, depending on the report ids, for which votings were conducted. If report has positive voting weight, then funds go 50-50%, 50% go to the report creater, and 50% goes to the people who voted positively. If report has negative voting weight, then 50% goes to the people who voted negatively. and 50% gets redistributed between the passed proposals based on their weights. The idea around this is to loop on all proposals, and at first process negative ones, and redistribute funds to the positive proposals, by redistributing weights. Afterwards we'll need tp loop again, and distribute tokens for the positive proposals.
## Third stage
## Pools deployments
------------------------------------------------------------------------------------------------------------------
DoinGud DAO is a project that allows to create a decentralized platform to create, moderate, fund and evaluate all possible different projects which have a good purposes. Overall tokenomics architecture is described below:

This architecture will require us to develop a set of Smart Contracts, which will satisfy the requirements.
## Main DAO(Guild Manager)
This Main part consists of the contracts described below:

### GnosisSafe
Avatar contract in our case is going to be a GnosisSafe multisig, which will store the funding collected by the multisig.
### Avatar
Avatar contract in our case is going to be a GnosisSafe multisig, which will store the funding collected by the multisig.
### Governor
Avatar contract in our case is going to be a GnosisSafe multisig, which will store the funding collected by the multisig.
### Decision Engine
Place to stake
{"metaMigratedAt":"2023-06-17T01:41:16.119Z","metaMigratedFrom":"Content","title":"DoinGud DAO TechSpec","breaks":true,"contributors":"[{\"id\":\"4f0b51bb-009a-441f-90cd-3ea31bf5ee34\",\"add\":24759,\"del\":12213},{\"id\":\"8c279649-5e42-40f8-aab0-379b6dcd3cbb\",\"add\":3720,\"del\":2697}]"}