From ac8f70a174e3545687bb410e4598392b5b618eb7 Mon Sep 17 00:00:00 2001 From: Peter Dragos Date: Mon, 24 Jan 2022 16:35:50 -0500 Subject: [PATCH 1/3] Update authority-tokens.md Leaving some comments/questions from my first read-through (starting in alphabetical order in `tech-design`). I'll probably have answered most of these by the time I'm finished going through all the docs, but it will do us well to make this as easy to read straight through as possible. General comments: ----- - It'd be good to pick an entry-point/give an overview in the README. This way you can keep track of when different concepts are introduced, and contributors to the spec will have a better idea of what they can assume their audience knows. - These docs are Liqwid-centric (and I believe I've skimmed earlier versions in the `liqwid-specs` repo) right now. We should decide whether we want to keep these specs focused on Liqwid, or if it would make sense to build up a small, hypothetical, minimum-viable-example that gets extended with Agora. The benefits of the former are that you can point to a real-world example of Agora's principles and implementation in practice; the latter could be more useful in a "here's how to integrate Agora into a project" tutorial --- docs/tech-design/authority-tokens.md | 31 +++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/docs/tech-design/authority-tokens.md b/docs/tech-design/authority-tokens.md index 584d2f9..7c4f6f4 100644 --- a/docs/tech-design/authority-tokens.md +++ b/docs/tech-design/authority-tokens.md @@ -18,7 +18,9 @@ ## Authority Tokens -In order to allow proposals to have a large number of potential effects, and to be extensible for different applications of governance, it is useful to have the effects be decided at a later time. In Ethereum systems, often times this is done by encoding some untyped data and calls to specific contract hashes. Compound encodes it with `address[] Proposal.targets` (the contracts to be called) and `bytes[] Proposal.calldatas` (the data to be passed). Of course, this doesn't quite translate to Cardano's EUTXO model, so we need to achieve this some different way. +In order to allow proposals to have a large number of potential effects, and to be extensible for different applications of governance, it is useful to have the effects be decided at a later time. In Ethereum systems, often times this is done by encoding some untyped data and calls to specific contract hashes. [Compound](https://medium.com/compound-finance/compound-governance-5531f524cf68) encodes it with `address[] Proposal.targets` (the contracts to be called) and `bytes[] Proposal.calldatas` (the data to be passed). Of course, this doesn't quite translate to Cardano's EUTXO model, so we need to achieve this some different way. + +> Peter, 2022-01-24: "(...) be decided at a later time". later with respect to what? This could mean the effect is decided after the proposal, or that Agora doesn't specify a fixed set of effects at compile-time/run-time, etc. If it's simple enough to state, it may be helpful to say "it is useful to have the effects be decided when (...) is known. In order to allow this flexibility, there are two facts that we rely on: - We trust the community to validate the proposal entirely, including whether or not the effects encoded in it are written correctly. (This may mean we have a set of known and trusted effects we agree are correct and safe, collectively) @@ -26,13 +28,31 @@ In order to allow this flexibility, there are two facts that we rely on: To achieve the former is rather simple, the effect validator's source code is available for anyone to look at, and it hashes correctly to the hash stored in the proposal itself. So, the LQ holders can decide on whether it is a positive for the system. +> Peter, 2022-01-24: At this point in reading, its not obvious that "effect"s have validators. This is likely explained elsewhere, but this should be kept in mind when considering the order in which these specs should be read. +> Peter, 2022-01-24: Update: after some more reading, it sounds like the Effect/GAT pair is basically a way to short-circuit the "normal" validation of a UTxO at one of the component addresses; it basically says "ignore your usual validation logic; I have a GAT, so this transaction must be approved". + In order to achieve the latter, we must introduce some way to give effects authority to perform their actions. We do this by handing out "Governance Authority Tokens" (GATs) to each of the the effects belonging to a proposal after the proposal passes. When these authority tokens are *burned*, they act as a way of saying "the DAO validated this, so trust that I will ensure this transaction is correct". -The components that need to be adjustable at a later point, will need to allow this as means for proving authority and validation of a transaction. So, for example, a Liqwid Market might need to have its parameters updated, the following diagram shows how this would happen after a proposal has successfully been voted on and passed: +The components that need to be adjustable at a later point will need to allow this as means for proving authority and validation of a transaction. So, for example, a Liqwid Market might need to have its parameters updated, the following diagram shows how this would happen after a proposal has successfully been voted on and passed: -![](../diagrams/GovernanceAuthorityToken.svg) +> Peter, 2022-01-24: RE: "(...) need to be adjustable at a (...)": could it make more sense to say "adjusted via governance"? + +![Governance Authority Token UTxO flow diagram](../diagrams/GovernanceAuthorityToken.svg) + +> Peter, 2022-01-24: You should add a link to what conventions you're following for you UTxO flows to the README + +> Peter 2022-01-24: I think I see what's going on here, but it could use some annotations/additional description. +> Tx1, a.) A proposal is closed via Tx1, and the transaction emits a continuing `Proposal` and `Governance` UtXO, +> along with an "Effect" UTxO (presumably identified in the content of the proposal). The Effect UTxO encodes effect `f` in it's validation logic. +> Question: where is this effect encoded? +> Tx1, b.) In the same transaction, a GAT is minted and paid to the UTxO. +> Tx1, c.) The `min utxo` ADA is paid to the Effect UTxO from "user inputs". I'm not certain where this is, but I'm assuming it's accumulated during voting or something? What is it used for? +> Tx2, a.) The Effect UTxO and the component to be governed are consumed in transaction 2. +> Tx2, b.) The Market's usual validation logic is short-circuited since the GAT was burned, and the continuing Market UTxO updates its datum. +> Tx2, c.) There is a continuing "Effect" UTxO; presumably, this serves as a proof that an effect has taken place? Meaning that a sequence of effects that require a particular order of execution can consume the output UTxO as a witness? +> Tx2, d.) The min ADA is paid to "user outputs"; is this just "collateral" to make sure that the effect is executed in a timely fashion? As a result of this approach, there's a number of benefits, but also details we need to watch out for: @@ -50,3 +70,8 @@ Having delegated the authority of *the entire system* in a single token is a lot - We have the transaction be executed by one of a number of community trusted members. This of course is something that is encoded in the effect, rather than anywhere else. Hopefully, this is sufficient to ensure the transactions are created correctly, and nothing unexpected slips in. This problem is no more complicated or dangerous than elsewhere where we delegate certain trust or authority to just the validation or movement of a token. + + +> 2022-01-24, Peter: Have you considered placing the validator hash of the effect script in the token name? This could tie a proposal to a GAT to a validator, instead of having any GAT work with any effect script. + +> 2022-01-24, Peter: This section could use some additional explaination/pseudo-code of the what the GAT minting policy would look like and what additional validation logic would go into a govern-able component From 31aa38e457f8027bc44ac1159d605028a773b1b6 Mon Sep 17 00:00:00 2001 From: Peter Dragos Date: Mon, 24 Jan 2022 17:04:35 -0500 Subject: [PATCH 2/3] proposal edits --- docs/tech-design/proposals.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/tech-design/proposals.md b/docs/tech-design/proposals.md index 3750bc7..1baf73b 100644 --- a/docs/tech-design/proposals.md +++ b/docs/tech-design/proposals.md @@ -20,7 +20,10 @@ This document gives an overview of technical design aspects of the Proposals sys ## Proposals -Initiating a proposal requires you to have more than a certain amount of LQ in the StakingPool (e.g. around 6-10 LQ). This is checked by consuming the proposer's stake utxo. Creating a proposal forges a proposal script state thread which is where all voting interactions happen with. Proposals are tracked in coordination with the governance, so it must be included in the transaction as well. +Initiating a proposal requires the initiator to have more than a certain amount of LQ in the StakingPool (e.g. around 6-10 LQ). This is checked by consuming the proposer's stake utxo. Creating a proposal forges a proposal script state thread which is where all voting interactions happen within. Proposals are tracked in coordination with the governance, so it must be included in the transaction as well. + +> Peter, 2022-01-24: "(...) than a certain amount of **LQ**". two questions: 1.) Is this up to date? 2.) Given that agora doesn't have a token, what should this token be called in the abstract? +> Peter, 2022-01-24: "(...) coordination with the governance": We've adopted the terminology in LiqwidX "Governor" to refer to the continuing UTxO that tracks governance-related activities, and use "governance" to refer to "what the Governor does/enables". Do you make the same distinction? ### Proposal voting @@ -54,12 +57,17 @@ A proposal fits into a state machine neatly. Draft being the starting state, and #### Draft phase -During the Draft phase, the proposal script has been minted. At this stage, only positive votes will count and for the proposal to get into the voting phase, a certain amount of LQ will have to be backing the proposal. The UTXO can be queried for any metadata it contains, should it contain any useful information. LQ holders can "cosign" the proposal and add their LQ in order to allow the motion to get into the voting phase. +During the Draft phase, the proposal script has been minted. At this stage, only votes in favor of cosigning the draft will count. For the proposal to get into the voting phase, a certain amount of LQ will have to be backing the proposal. The UTXO can be queried for any metadata it contains, should it contain any useful information. LQ holders can "cosign" the proposal and add their LQ in order to allow the motion to get into the voting phase. + +> Peter, 2022-01-24: "(...) the proposal script has been minted." I think this should be "the draft proposal's state thread token has been minted and paid to the proposal's UTxO." +> Peter, 2022-01-24: "(...) a certain amount of LQ": how much? Where is this set/calculated? #### Voting phase During the voting phase a voter can submit a vote either in favour or against the proposal. This simply adds their PubKey to the list of votes as a state-machine action. By virtue of being a state-machine action, this causes contention, and may be rate-limited through some means. +> Peter, 2022-01-24: What happens in the event of a tie? How are the votes tailled? Is it always simple majority, or are more complex [social choice procedures](https://en.wikipedia.org/wiki/Social_choice_theory) in-scope for Agora (even if its V2, V3...) + ##### What determines a successful proposal? When initializing a proposal, the governance's thresholds are passed along, one of the thresholds is the `quorum`. @@ -68,7 +76,9 @@ When initializing a proposal, the governance's thresholds are passed along, one After the voting phase has completed, the proposal has either passed, or failed. -We wait a set time before allowing execution of the proposal's effects. This is to allow LQ holders time to prepare for the change in whichever way they seem fit. This is also a security mechanism, should the system be at risk of hostile takeover. +We wait a set time before allowing execution of the proposal's effects. This is to allow LQ holders time to prepare for the change in whichever way they see fit. This is also a security mechanism, should the system be at risk of hostile takeover. + +> Peter, 2022-01-24: How is this time decided? Are you familiar with the "Emergency Shutdown Mode" of MakerDAO, which we'll be adopting in LiqwidX? This is something that would, for the most part, need to happen ASAP. What sort of modularity exists or would you like to see? #### Execution phase @@ -79,3 +89,5 @@ In the case of a successful proposal, anyone can execute the effects, as it can There is a deadline for how long it can take for the proposal to get executed. Again, as the proposal is necessarily something that has been agreed by the voters, it will be incentivized naturally to be executed. See [tech-design/authority-token.md](./authority-tokens.md) for how effects take place after execution + +> Peter 2022-01-24: I _think_ it may be useful to have some way to witness on-chain whether a proposal succeeded or failed, and by what margins. I'm not certain whether this would be possible with what you currently have in mind, but it could allow for a more expressive governenace structure or allow for other actions to depend on the success/failure of proposals that aren't directly part of the system being governed (i.e., a validator that only locks/unlocks value if a proposal goes a certain way). From 6cdc4516cf73b8db205d9fbe044726227a1de1fa Mon Sep 17 00:00:00 2001 From: Peter Dragos Date: Mon, 24 Jan 2022 17:14:16 -0500 Subject: [PATCH 3/3] staking pool edits --- docs/tech-design/staking-pool.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/tech-design/staking-pool.md b/docs/tech-design/staking-pool.md index a887fec..fda84f3 100644 --- a/docs/tech-design/staking-pool.md +++ b/docs/tech-design/staking-pool.md @@ -20,6 +20,8 @@ In order to be able to count votes at all, some means of proving a user's skin in the game on-chain must exist. We propose having a central StakingPool contract which mints separate per-user UTXOs in which the governance token can be deposited. The MintingPolicy of the state threads ensures that it is paid to the script and with valid initial state. This circumvents the need for a central token, and makes the minting of such tokens concurrently possible. +> Peter, 2022-01-24: "(...) mints separate per-user UTxOs (...)": I think this should read something like "locks per-user continuing UTxOs carrying unique state-thread tokens in which the governance token can be deposited." What do you think? + ### Stake UTXOs A stake UTXO stores the information to allow accessing your staked GT as if it was a safe. @@ -35,6 +37,8 @@ data Stake = Stake } ``` +> Peter, 2022-01-24: What happens is `lockedByProposals` grows too large? I know its unlikely, but have you considered devising a way circumvent this from being a possibility? + When voting for a proposal, the Stake UTXO is used to witness the user's staked amount. As a result, the two following state transitions take place (pseudocode): ```haskell @@ -46,6 +50,8 @@ A sort of mutual binding between the proposal and the stake is created and undoi Depositing and withdrawing is made illegal when `stake.lockedByProposals` isn't empty. Withdrawing is illegal so that you can't have GT in a vote, without having it anymore, whereas Depositing is illegal so that you can't deposit after a vote and unvote it again in order to retract more than you originally voted. Thus preserving that +> Peter, 2022-01-24: "Thus preserving that..." (incomplete sentence) + #### Delegating stake Most things like Cosigning sort of work trivially by just witnessing Stake, but delegation requires an extra step. We add a field to what `Stake` stores.