diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..bb726d9 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,19 @@ +# Overview + +## What is Llama? + +Llama is an onchain governance and access control framework for smart contracts. + +Using Llama, teams can deploy fully independent instances that define granular roles and permissions for executing transactions, known as "actions". + +Llama instances can adapt to a changing environment by incrementally adding new participants and expanding the set of available actions. Actions can be any operation that is represented by invoking a smart contract function. This includes transferring funds, updating a registry, changing protocol parameters, or activating an emergency pause. + +Learn more about Llama by reading [the protocol documentation](https://github.com/llamaxyz/llama/tree/main/docs) in the llama repository. + +## What is Llama Periphery? + +This repository contains supporting modules for operating Llama instances. Modules are extensions to Llama instances that can be adopted by using a Llama action to configure and deploy. + +## Modules + +- [Token Voting](https://github.com/llamaxyz/llama-periphery/tree/main/docs/token-voting/README.md): smart contract policies that allow voting token holders to create actions enforced by delegated token thresholds or collectively approve or disapprove an action through token voting. diff --git a/docs/token-voting/README.md b/docs/token-voting/README.md new file mode 100644 index 0000000..b2f3b23 --- /dev/null +++ b/docs/token-voting/README.md @@ -0,0 +1,9 @@ +# Llama Token Voting + +Llama Token Voting is extensions to Llama instances. They allow token holders to create actions and collectively cast approvals or disapprovals. The `LlamaTokenGovernor` contract follows established token voting framework best practices and is designed to integrate directly with instances. + +Llama Token Voting consists of two components: + +- [Token Governor](/docs/token-voting/TokenGovernor.md) + +- [Token Voting Factory](/docs/token-voting/Factory.md) \ No newline at end of file diff --git a/docs/token-voting/token-governor.md b/docs/token-voting/token-governor.md new file mode 100644 index 0000000..40897c1 --- /dev/null +++ b/docs/token-voting/token-governor.md @@ -0,0 +1,100 @@ +# Llama Token Governor + +`LlamaTokenGovernor` is the contract that enables token holders to create actions and cast votes/vetoes. + +Llama Token Voting works by issuing a Llama policy to the `LlamaTokenGovernor` contract, which can hold roles and permissions that enable the contract to cast approvals/disapprovals and create actions. The Governor contract exposes this policyholder functionality via public functions to token holders. + +## Voting Periods + +There are three distinct periods during a voting cycle: + +- The delay period +- The casting period +- The submission period + +Llama Token Voting process begins with a delay period. This period is calculated by multiplying the `delayPeriodPct` by the action's approval or disapproval period. The purpose of the delay period is to provide token holders a window to delegate their tokens before voting balances are crystallized for the duration of the vote. + +The casting period is when token holders vote/veto a pending action. It is calculated as the product of the `votingPeriodPct` and the action's approval or disapproval period. It automatically begins at the end of the delay period. + +Finally, the submission period is when the result is submitted to the instance's `LlamaCore` contract if consensus is reached. It is calculated by subtract the `delayPeriodPct` and `votingPeriodPct` from `ONE_HUNDRED_IN_BPS`. It automatically begins at the end of the casting period. + +## Casting Votes/Vetoes + +The `LlamaTokenGovernor` contract allows token holders to participate in the governance process by casting votes/vetoes on actions. This functionality is crucial for the decentralized decision-making process, ensuring that the actions reflect the collective will of the token holders. + +### Delay Period + +The Llama Token Voting process begins with a delay period. This period is calculated by multiplying the `delayPeriodPct` by the action's approval or disapproval period. The purpose of the delay period is to provide token holders a window to delegate their tokens before voting balances are crystallized for the duration of the token vote. + +This checkpoint occurs at the conclusion of the delay period, so any token transfers or delegation updates after the checkpoint will have no affect on this action's token voting process. + +### Casting Votes + +Token holders can cast their votes during the casting period on actions created within the Llama governance system if the Governor holds the approval or force approval role for the action's strategy. The process of casting a vote involves indicating support or opposition to a particular action. The contract provides the `castVote` function, which requires the following parameters: + +```solidity + uint8 role, + ActionInfo actionInfo, + uint8 support, + string reason +``` + +- Role: This parameter specifies the role of the token holder in the governance process. It is used to determine the permission ID of the `LlamaTokenGovernor`. +- ActionInfo: This struct contains all the necessary information about the action on which the vote is being cast, including the action ID, creator, strategy, target, value, and data. +- Support: Indicates the token holder's stance on the action. The values can be: + - 0 for Against + - 1 for For + - 2 for Abstain +- Reason: A human-readable string providing the rationale behind the token holder's vote. + +The function returns the weight of the cast, representing the influence of the token holder's vote based on their token balance. + +### Casting Vetoes + +In addition to casting votes, token holders also have the ability to cast vetoes. + +The `castVeto` function is similar to castVote and requires the same parameters. The parameters have the same meaning as in the castVote function. The support parameter, in this context, indicates the token holder's stance on vetoing the action. + +### Reaching Quorum and Approval + +Quorum is calculated using the amount of `For` votes. `Abstain` votes do not count towards the quorum. + +Approval is reached when the quorum is met, and the `For` votes surpass the `Against` votes. + +### Submitting Results + +Once the casting period is over, the result can be submitted. + +If the action has not passed, no action needs to be taken. + +If the action has passed, anyone now can call the `submitApproval` or `submitDisapproval` function depending on if the action is being voted or vetoed. The submit functions must be called before the end of the submission period, otherwise it expires. + +## Creating Actions + +Token holders can create actions on the Llama instance if they have a sufficient token balance. + +The `creationThreshold` is the number of tokens required to create an action; it can be updated by the token governor's instance. + +To create an action, a user must call the `createAction` function which has the following fields: + +```solidity + uint8 role, + ILlamaStrategy strategy, + address target, + uint256 value, + bytes data, + string description +``` + +- Role: The role that will be used to determine the permission ID of the `LlamaTokenGovernor`. +- Strategy: The strategy contract that will determine how the action is executed. +- Target: The contract called when the action is executed. +- Value: The value in wei to be sent when the action is executed. +- Data: Data to be called on the target when the action is executed. +- Description: A human readable description of the action and the changes it will enact. + +Note that if the Governor itself does not have the permission to create the action on the instance's `LlamaCore`, `createAction` will fail. + +The action creation process is the same as the core Llama system, but instead of creating actions based on the user's policy and permissions the Governor's validation check is based on if they hold enough tokens. + +If unfamiliar with the canonical Llama action creation process, our the main [Llama docs](https://github.com/llamaxyz/llama/tree/main/docs) will help. diff --git a/docs/token-voting/token-voting-factory.md b/docs/token-voting/token-voting-factory.md new file mode 100644 index 0000000..66b2859 --- /dev/null +++ b/docs/token-voting/token-voting-factory.md @@ -0,0 +1,27 @@ +# Llama Token Voting Factory + +The `LlamaTokenVotingFactory` contract enables the deployment of Llama Token Voting. This factory contract deploys a new `LlamaTokenGovernor` and `LlamaTokenAdapter`. These two contracts comprise Llama Token Voting which is how holders of a specified token can participate in Llama governance. + +## Deployment + +To Deploy a `LlamaTokenGovernor` and a `LlamaTokenAdapter` through the `LlamaTokenVotingFactory`, a `LlamaTokenVotingConfig` struct is passed to the deploy method on the factory contract. + +At deploy time, a `LlamaTokenAdapter` logic contract and config are passed to the factory's deploy function. + +### Token Adapters + +`LlamaTokenAdapter` allow the `LlamaTokenGovernor` to connect to many different implementations of tokens. + +We've implemented a `LlamaTokenAdapter` that works with ERC20 and ERC721 tokens that implement the [IVotes interface](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/governance/utils/IVotes.sol) and checkpoint supply using `block.timestamp`. + +Many tokens checkpoint using `block.number`, or have different method names than the `IVotes` interface. The purpose of the adapter is to provide a constant interface for the governor, while being flexible to handle many different token implementations. + +Currently only timestamp based tokens are supported, but we can extend functionality to tokens that checkpoint in block number by writing a new adapter. + +## Integrating with a Llama instance + +A dedicated role and policy with the corresponding role to the `LlamaTokenVotingGovernor` contract. + +In order for token holders to approve or disapprove actions, Strategies have to utilize the `LlamaTokenVotingGovernor` as the approval or disapproval role so token holders can vote on certain actions. + +Additionally, Permissions can be issued to the governor contract so that policyholders can create certain actions on your Llama instance.