Skip to content
This repository has been archived by the owner on Nov 27, 2024. It is now read-only.

Commit

Permalink
feat: merge LlamaTokenActionCreator and LlamaTokenCaster contract…
Browse files Browse the repository at this point in the history
…s into one `LlamaTokenGovernor` contract (#79)

**Motivation:**

This PR reduces complexity of token voting modules by using a single
contract to manage the entire action creating and casting lifecycle.

**Modifications:**

Merge the functionality of `LlamaTokenActionCreator` and
`LlamaTokenCaster` into a single contract.

**Result:**

Users only need to rely on a token adapter and token governor to handle
token voting.

---------

Co-authored-by: Rajath Alex <[email protected]>
  • Loading branch information
AustinGreen and 0xrajath authored Dec 18, 2023
1 parent 444beed commit 1ae0a79
Show file tree
Hide file tree
Showing 15 changed files with 847 additions and 1,106 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ The comments in that file explain what each variable is for and when they're nee
- `just deploy` - deploy and verify payload on mainnet
- Run `just -l` or see the [`justfile`](https://github.com/llamaxyz/llama/blob/main/justfile) for other commands such as dry runs.

## Testnet deployment

| Name | Sepolia |
| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
|_Factory_|
| LlamaTokenVotingFactory | [0x6A97643633eafEEC00b7Ec4CE84269203645aaBC](https://sepolia.etherscan.io/address/0x6A97643633eafEEC00b7Ec4CE84269203645aaBC) |
|_Governor_|
| LlamaTokenGovernor (logic contract) | [0x0A01C701013E6d6F1c1759457324303Bf25CC7E3](https://sepolia.etherscan.io/address/0x0A01C701013E6d6F1c1759457324303Bf25CC7E3) |
|_Token Adapters_|
| LlamaTokenAdapterVotesTimestamp (logic contract) | [0x8CCe1b824EfF3A7966348528B6951A84eC0541A5](https://sepolia.etherscan.io/address/0x8CCe1b824EfF3A7966348528B6951A84eC0541A5) |

## Smart contract reference

Run the following command to generate smart contract reference documentation from our NatSpec comments and serve those static files locally:
Expand Down
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
fuzz = { runs = 5000 }
invariant = { runs = 1000, depth = 100 }
optimizer = true
optimizer_runs = 10_000_000
optimizer_runs = 19_000
via_ir = false

[rpc_endpoints]
Expand Down
18 changes: 5 additions & 13 deletions script/DeployLlamaTokenVotingFactory.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ pragma solidity 0.8.23;
import {Script} from "forge-std/Script.sol";

import {DeployUtils} from "script/DeployUtils.sol";
import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol";
import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol";
import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol";
import {LlamaTokenVotingFactory} from "src/token-voting/LlamaTokenVotingFactory.sol";
import {LlamaTokenAdapterVotesTimestamp} from "src/token-voting/token-adapters/LlamaTokenAdapterVotesTimestamp.sol";

contract DeployLlamaTokenVotingFactory is Script {
// Logic contracts.
LlamaTokenActionCreator llamaTokenActionCreatorLogic;
LlamaTokenCaster llamaTokenCasterLogic;
LlamaTokenGovernor llamaTokenGovernorLogic;
LlamaTokenAdapterVotesTimestamp llamaTokenAdapterTimestampLogic;

// Factory contracts.
Expand All @@ -24,17 +22,11 @@ contract DeployLlamaTokenVotingFactory is Script {
);

vm.broadcast();
llamaTokenActionCreatorLogic = new LlamaTokenActionCreator();
DeployUtils.print(
string.concat(" LlamaTokenActionCreatorLogic: ", vm.toString(address(llamaTokenActionCreatorLogic)))
);

vm.broadcast();
llamaTokenCasterLogic = new LlamaTokenCaster();
DeployUtils.print(string.concat(" LlamaTokenCasterLogic: ", vm.toString(address(llamaTokenCasterLogic))));
llamaTokenGovernorLogic = new LlamaTokenGovernor();
DeployUtils.print(string.concat(" LlamaTokenGovernorLogic: ", vm.toString(address(llamaTokenGovernorLogic))));

vm.broadcast();
tokenVotingFactory = new LlamaTokenVotingFactory(llamaTokenActionCreatorLogic, llamaTokenCasterLogic);
tokenVotingFactory = new LlamaTokenVotingFactory(llamaTokenGovernorLogic);
DeployUtils.print(string.concat(" LlamaTokenVotingFactory: ", vm.toString(address(tokenVotingFactory))));

vm.broadcast();
Expand Down
11 changes: 4 additions & 7 deletions script/DeployLlamaTokenVotingModule.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {DeployUtils} from "script/DeployUtils.sol";
import {ILlamaCore} from "src/interfaces/ILlamaCore.sol";
import {CasterConfig, LlamaTokenVotingConfig} from "src/lib/Structs.sol";
import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol";
import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol";
import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol";
import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol";
import {LlamaTokenVotingFactory} from "src/token-voting/LlamaTokenVotingFactory.sol";
import {DeployUtils} from "script/DeployUtils.sol";

Expand All @@ -36,17 +35,15 @@ contract DeployLlamaTokenVotingModule is Script {
ILlamaTokenAdapter(jsonInput.readAddress(".tokenAdapterLogic")),
DeployUtils.readTokenAdapter(jsonInput),
abi.decode(jsonInput.parseRaw(".nonce"), (uint256)),
abi.decode(jsonInput.parseRaw(".actionCreatorRole"), (uint8)),
abi.decode(jsonInput.parseRaw(".casterRole"), (uint8)),
abi.decode(jsonInput.parseRaw(".governorRole"), (uint8)),
abi.decode(jsonInput.parseRaw(".creationThreshold"), (uint256)),
casterConfig
);

vm.broadcast(deployer);
(LlamaTokenActionCreator actionCreator, LlamaTokenCaster caster) = factory.deploy(config);
LlamaTokenGovernor governor = factory.deploy(config);

DeployUtils.print("Successfully deployed a new Llama token voting module");
DeployUtils.print(string.concat(" LlamaTokenActionCreator: ", vm.toString(address(actionCreator))));
DeployUtils.print(string.concat(" LlamaTokenCaster: ", vm.toString(address(caster))));
DeployUtils.print(string.concat(" LlamaTokenGovernor: ", vm.toString(address(governor))));
}
}
7 changes: 3 additions & 4 deletions script/input/11155111/tokenVotingModuleConfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"comment": "This is an example token voting module deployment on Sepolia.",
"factory": "0x2997f4D6899DC91dE9Ae0FcD98b49CA88b8Fc85e",
"factory": "0x6A97643633eafEEC00b7Ec4CE84269203645aaBC",
"llamaCore": "0xc68046794327490F953EA15522367FFBA0b64f86",
"tokenAdapterLogic": "0x88D63b8c5F8C3e95743F1d26Df8aDd0669614278",
"tokenAdapterLogic": "0x8CCe1b824EfF3A7966348528B6951A84eC0541A5",
"tokenAddress": "0xf44d44a54440F22e5DC5adb7efA3233645f04007",
"nonce": 0,
"actionCreatorRole": 0,
"casterRole": 0,
"governorRole": 0,
"creationThreshold": 10000e18,
"casterConfig": {
"voteQuorumPct": 2000,
Expand Down
41 changes: 20 additions & 21 deletions src/lib/Structs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,6 @@ struct Action {
uint96 totalDisapprovals; // The total quantity of policyholder disapprovals.
}

/// @dev Configuration of a new Llama token voting module.
struct LlamaTokenVotingConfig {
ILlamaCore llamaCore; // The address of the Llama core.
ILlamaTokenAdapter tokenAdapterLogic; // The logic contract of the token adapter.
bytes adapterConfig; // The configuration of the token adapter.
uint256 nonce; // The nonce to be used in the salt of the deterministic deployment.
uint8 actionCreatorRole; // The role required by the `LlamaTokenActionCreator` to create an action.
uint8 casterRole; // The role required by the `LlamaTokenCaster` to cast approvals and disapprovals.
uint256 creationThreshold; // The number of tokens required to create an action.
CasterConfig casterConfig; // The quorum and period data for the `LlamaTokenCaster`.
}

/// @dev Quorum and period data for token voting caster contracts.
struct CasterConfig {
uint16 voteQuorumPct;
uint16 vetoQuorumPct;
uint16 delayPeriodPct;
uint16 castingPeriodPct;
uint16 submissionPeriodPct;
}

/// @dev Data that represents a permission.
struct PermissionData {
address target; // Contract being called by an action.
Expand Down Expand Up @@ -98,3 +77,23 @@ struct LlamaPolicyConfig {
string color; // The primary color of the SVG representation of the instance's policy (e.g. #00FF00).
string logo; // The SVG string representing the logo for the deployed Llama instance's NFT.
}

/// @dev Configuration of a new Llama token voting module.
struct LlamaTokenVotingConfig {
ILlamaCore llamaCore; // The address of the Llama core.
ILlamaTokenAdapter tokenAdapterLogic; // The logic contract of the token adapter.
bytes adapterConfig; // The configuration of the token adapter.
uint256 nonce; // The nonce to be used in the salt of the deterministic deployment.
uint8 governorRole; // The role required by the `LlamaTokenGovernor` to create actions and cast on them.
uint256 creationThreshold; // The number of tokens required to create an action.
CasterConfig casterConfig; // The quorum and period data for the `LlamaTokenGovernor`.
}

/// @dev Quorum and period data for token voting caster contracts.
struct CasterConfig {
uint16 voteQuorumPct;
uint16 vetoQuorumPct;
uint16 delayPeriodPct;
uint16 castingPeriodPct;
uint16 submissionPeriodPct;
}
Loading

0 comments on commit 1ae0a79

Please sign in to comment.