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

chore: add script to deploy token voting modules #74

Merged
merged 8 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ run-script script_name flags='' sig='' args='':
-vvvv {{flags}}
mv _test test

run-deploy-voting-module-script flags: (run-script 'DeployLlamaTokenVotingModule' flags '--sig "run(address,string)"' '$SCRIPT_DEPLOYER_ADDRESS "tokenVotingModuleConfig.json"')

dry-run-deploy: (run-script 'DeployLlamaTokenVotingFactory')

deploy: (run-script 'DeployLlamaTokenVotingFactory' '--broadcast --verify --build-info --build-info-path build_info')

dry-run-deploy-voting-module: (run-deploy-voting-module-script '')

deploy-voting-module: (run-deploy-voting-module-script '--broadcast --verify')

verify: (run-script 'DeployLlamaTokenVotingFactory' '--verify --resume')
52 changes: 52 additions & 0 deletions script/DeployLlamaTokenVotingModule.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {Script, stdJson} from "forge-std/Script.sol";

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 {LlamaTokenVotingFactory} from "src/token-voting/LlamaTokenVotingFactory.sol";
import {DeployUtils} from "script/DeployUtils.sol";

contract DeployLlamaTokenVotingModule is Script {
using stdJson for string;

function run(address deployer, string memory configFile) public {
string memory jsonInput = DeployUtils.readScriptInput(configFile);

LlamaTokenVotingFactory factory = LlamaTokenVotingFactory(jsonInput.readAddress(".factory"));

DeployUtils.print(string.concat("Deploying Llama token voting module to chain:", vm.toString(block.chainid)));

CasterConfig memory casterConfig = CasterConfig(
abi.decode(jsonInput.parseRaw(".casterConfig.voteQuorumPct"), (uint16)),
abi.decode(jsonInput.parseRaw(".casterConfig.vetoQuorumPct"), (uint16)),
abi.decode(jsonInput.parseRaw(".casterConfig.delayPeriodPct"), (uint16)),
abi.decode(jsonInput.parseRaw(".casterConfig.castingPeriodPct"), (uint16)),
abi.decode(jsonInput.parseRaw(".casterConfig.submissionPeriodPct"), (uint16))
);

LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig(
ILlamaCore(jsonInput.readAddress(".llamaCore")),
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(".creationThreshold"), (uint256)),
casterConfig
);

vm.broadcast(deployer);
(LlamaTokenActionCreator actionCreator, LlamaTokenCaster caster) = 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))));
}
}
21 changes: 20 additions & 1 deletion script/DeployUtils.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {console2} from "forge-std/Script.sol";
import {VmSafe} from "forge-std/Vm.sol";
import {console2, stdJson} from "forge-std/Script.sol";

import {LlamaTokenAdapterVotesTimestamp} from "src/token-voting/token-adapters/LlamaTokenAdapterVotesTimestamp.sol";

library DeployUtils {
using stdJson for string;

address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code"))));
VmSafe internal constant VM = VmSafe(VM_ADDRESS);

function readScriptInput(string memory filename) internal view returns (string memory) {
string memory inputDir = string.concat(VM.projectRoot(), "/script/input/");
string memory chainDir = string.concat(VM.toString(block.chainid), "/");
return VM.readFile(string.concat(inputDir, chainDir, filename));
}

function print(string memory message) internal view {
// Avoid getting flooded with logs during tests. Note that fork tests will show logs with this
// approach, because there's currently no way to tell which environment we're in, e.g. script
// or test. This is being tracked in https://github.com/foundry-rs/foundry/issues/2900.
if (block.chainid != 31_337) console2.log(message);
}

function readTokenAdapter(string memory jsonInput) internal pure returns (bytes memory) {
address tokenAddress = jsonInput.readAddress(".tokenAddress");
return abi.encode(LlamaTokenAdapterVotesTimestamp.Config(tokenAddress));
}
}
18 changes: 18 additions & 0 deletions script/input/11155111/tokenVotingModuleConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"comment": "This is an example token voting module deployment on Sepolia.",
"factory": "0x2997f4D6899DC91dE9Ae0FcD98b49CA88b8Fc85e",
"llamaCore": "0xc68046794327490F953EA15522367FFBA0b64f86",
"tokenAdapterLogic": "0x88D63b8c5F8C3e95743F1d26Df8aDd0669614278",
"tokenAddress": "0xf44d44a54440F22e5DC5adb7efA3233645f04007",
"nonce": 0,
"actionCreatorRole": 0,
"casterRole": 0,
"creationThreshold": 10000e18,
"casterConfig": {
"voteQuorumPct": 2000,
"vetoQuorumPct": 1000,
"delayPeriodPct": 2500,
"castingPeriodPct": 5000,
"submissionPeriodPct": 2500
}
}
14 changes: 14 additions & 0 deletions src/lib/Structs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
pragma solidity ^0.8.23;

import {ILlamaAccount} from "src/interfaces/ILlamaAccount.sol";
import {ILlamaCore} from "src/interfaces/ILlamaCore.sol";
import {ILlamaActionGuard} from "src/interfaces/ILlamaActionGuard.sol";
import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol";
import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol";
import {RoleDescription} from "src/lib/UDVTs.sol";

/// @dev Data required to create an action.
Expand Down Expand Up @@ -34,6 +36,18 @@ 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;
Expand Down
18 changes: 1 addition & 17 deletions src/token-voting/LlamaTokenVotingFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.23;
import {Clones} from "@openzeppelin/proxy/Clones.sol";

import {ILlamaCore} from "src/interfaces/ILlamaCore.sol";
import {CasterConfig} from "src/lib/Structs.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";
Expand All @@ -13,22 +13,6 @@ import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol";
/// @author Llama ([email protected])
/// @notice This contract enables Llama instances to deploy a token voting module.
contract LlamaTokenVotingFactory {
// =========================
// ======== Structs ========
// =========================

/// @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`.
}

// ========================
// ======== Errors ========
// ========================
Expand Down
12 changes: 6 additions & 6 deletions test/token-voting/LlamaTokenVotingFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {Clones} from "@openzeppelin/proxy/Clones.sol";

import {LlamaTokenVotingTestSetup} from "test/token-voting/LlamaTokenVotingTestSetup.sol";

import {ActionInfo, CasterConfig} from "src/lib/Structs.sol";
import {ActionInfo, LlamaTokenVotingConfig} from "src/lib/Structs.sol";
import {ILlamaCore} from "src/interfaces/ILlamaCore.sol";
import {ILlamaPolicy} from "src/interfaces/ILlamaPolicy.sol";
import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol";
Expand Down Expand Up @@ -82,7 +82,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {

function test_CanDeployERC20TokenVotingModule() public {
bytes memory adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc20VotesToken)));
LlamaTokenVotingFactory.LlamaTokenVotingConfig memory config = LlamaTokenVotingFactory.LlamaTokenVotingConfig(
LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig(
CORE,
llamaTokenAdapterTimestampLogic,
adapterConfig,
Expand Down Expand Up @@ -159,7 +159,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {

function test_CanDeployERC721TokenVotingModule() public {
bytes memory adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc721VotesToken)));
LlamaTokenVotingFactory.LlamaTokenVotingConfig memory config = LlamaTokenVotingFactory.LlamaTokenVotingConfig(
LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig(
CORE,
llamaTokenAdapterTimestampLogic,
adapterConfig,
Expand Down Expand Up @@ -285,7 +285,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
block.chainid
);

LlamaTokenVotingFactory.LlamaTokenVotingConfig memory config = LlamaTokenVotingFactory.LlamaTokenVotingConfig(
LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig(
CORE,
llamaTokenAdapterTimestampLogic,
adapterConfig,
Expand Down Expand Up @@ -317,7 +317,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
/////////////////////

bytes memory adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc20VotesToken)));
LlamaTokenVotingFactory.LlamaTokenVotingConfig memory config = LlamaTokenVotingFactory.LlamaTokenVotingConfig(
LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig(
CORE,
llamaTokenAdapterTimestampLogic,
adapterConfig,
Expand Down Expand Up @@ -380,7 +380,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
//////////////////////

adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc20VotesToken)));
config = LlamaTokenVotingFactory.LlamaTokenVotingConfig(
config = LlamaTokenVotingConfig(
CORE,
llamaTokenAdapterTimestampLogic,
adapterConfig,
Expand Down
7 changes: 3 additions & 4 deletions test/token-voting/LlamaTokenVotingTestSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ import {LlamaPeripheryTestSetup} from "test/LlamaPeripheryTestSetup.sol";

import {DeployLlamaTokenVotingFactory} from "script/DeployLlamaTokenVotingFactory.s.sol";

import {Action, ActionInfo, CasterConfig} from "src/lib/Structs.sol";
import {Action, ActionInfo, CasterConfig, LlamaTokenVotingConfig} from "src/lib/Structs.sol";
import {ILlamaPolicy} from "src/interfaces/ILlamaPolicy.sol";
import {ILlamaRelativeStrategyBase} from "src/interfaces/ILlamaRelativeStrategyBase.sol";
import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol";
import {RoleDescription} from "src/lib/UDVTs.sol";
import {LlamaTokenAdapterVotesTimestamp} from "src/token-voting/token-adapters/LlamaTokenAdapterVotesTimestamp.sol";
import {LlamaTokenVotingFactory} from "src/token-voting/LlamaTokenVotingFactory.sol";
import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol";
import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol";

Expand Down Expand Up @@ -109,7 +108,7 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV

function _deployERC20TokenVotingModuleAndSetRole() internal returns (LlamaTokenActionCreator, LlamaTokenCaster) {
bytes memory adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc20VotesToken)));
LlamaTokenVotingFactory.LlamaTokenVotingConfig memory config = LlamaTokenVotingFactory.LlamaTokenVotingConfig(
LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig(
CORE,
llamaTokenAdapterTimestampLogic,
adapterConfig,
Expand Down Expand Up @@ -138,7 +137,7 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV

function _deployERC721TokenVotingModuleAndSetRole() internal returns (LlamaTokenActionCreator, LlamaTokenCaster) {
bytes memory adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc721VotesToken)));
LlamaTokenVotingFactory.LlamaTokenVotingConfig memory config = LlamaTokenVotingFactory.LlamaTokenVotingConfig(
LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig(
CORE,
llamaTokenAdapterTimestampLogic,
adapterConfig,
Expand Down
Loading