Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
88 changes: 88 additions & 0 deletions scripts/vote_2025_MM_DD.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""
# TODO Vote 2025_<MM>_<DD>

# TODO <a list of vote items synced with Notion Omnibus checklist>

# TODO (after vote) Vote #{vote number} passed & executed on ${date+time}, block ${blockNumber}.
"""


import time

from typing import Dict
from brownie import interface
from utils.voting import bake_vote_items, confirm_vote_script, create_vote
from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description
from utils.config import (
get_deployer_account,
get_is_live,
get_priority_fee,
)
from utils.mainnet_fork import pass_and_exec_dao_vote

# TODO <list all contract addresses used in a vote>

IPFS_DESCRIPTION = """
# TODO <IPFS description provided by DAO Ops>
"""

# TODO <helper functions>

def start_vote(tx_params: Dict[str, str], silent: bool = False):
# TODO arrange all variables neccessary for the vote

vote_desc_items, call_script_items = zip(
# TODO <vote items group 1>
(
"1. TODO <vote item description 1>",
# TODO <vote item 1>,
),
(
"2. TODO <vote item description 2>",
# TODO <vote item 2>,
),

# TODO <vote items group 2>
(
"3. TODO <vote item description 3>",
# TODO <vote item 3>,
),
(
"4. TODO <vote item description 4>",
# TODO <vote item 4>,
),
)

vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items))

if silent:
desc_ipfs = calculate_vote_ipfs_description(IPFS_DESCRIPTION)
else:
desc_ipfs = upload_vote_ipfs_description(IPFS_DESCRIPTION)

return confirm_vote_script(vote_items, silent, desc_ipfs) and list(
create_vote(vote_items, tx_params, desc_ipfs=desc_ipfs)
)


def main():
tx_params = {"from": get_deployer_account()}
if get_is_live():
tx_params["priority_fee"] = get_priority_fee()

vote_id, _ = start_vote(tx_params=tx_params, silent=False)

vote_id >= 0 and print(f"Vote created: {vote_id}.")


def start_and_execute_vote_on_fork_manual():
if get_is_live():
raise Exception("This script is for local testing only.")

tx_params = {"from": get_deployer_account()}
vote_id, _ = start_vote(tx_params=tx_params, silent=True)

time.sleep(5) # hack for waiting thread #2.

print(f"Vote created: {vote_id}.")
pass_and_exec_dao_vote(int(vote_id), step_by_step=True)
81 changes: 81 additions & 0 deletions tests/_test_2025_MM_DD.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from brownie import chain, interface
# TODO import voting script
from scripts.<vote_2025_MM_DD> import start_vote
from brownie.network.transaction import TransactionReceipt
from utils.test.tx_tracing_helpers import *


# TODO list all contract addresses used in tests - do not use imports from config!
DUAL_GOVERNANCE = "0xcdF49b058D606AD34c5789FD8c3BF8B3E54bA2db"
EMERGENCY_PROTECTED_TIMELOCK = "0xCE0425301C85c5Ea2A0873A2dEe44d78E02D2316"
DUAL_GOVERNANCE_ADMIN_EXECUTOR = "0x23E0B465633FF5178808F4A75186E2F2F9537021"
VOTING = "0x2e59A20f205bB85a89C53f1936454680651E618e"
vote_events_count = # TODO <# of events emitted by the vote>
dg_proposal_id = # TODO (if DG proposal exists in vote) <order # of a dg proposal>


def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, stranger):

# =======================================================================
# ========================= Arrange variables ===========================
# =======================================================================
# TODO arrange all variables necessary for the test
dual_governance = interface.DualGovernance(DUAL_GOVERNANCE)
timelock = interface.EmergencyProtectedTimelock(EMERGENCY_PROTECTED_TIMELOCK)
voting = interface.Voting(VOTING)

# =======================================================================
# ========================= Before voting tests =========================
# =======================================================================
# TODO run asserts that check the "before" vote state

# =======================================================================
# ============================== Voting =================================
# =======================================================================
vote_id = vote_ids_from_env[0] if vote_ids_from_env else start_vote({"from": ldo_holder}, silent=True)[0]
vote_tx: TransactionReceipt = helpers.execute_vote(vote_id=vote_id, accounts=accounts, dao_voting=voting)

# =======================================================================
# ========================= After voting tests ==========================
# =======================================================================
# TODO run asserts that check the "after" vote state

# TODO run vote happy path tests

# =======================================================================
# ====================== Before DG Proposal tests =======================
# =======================================================================
# TODO (if DG proposal exists in vote) run asserts that checks the "before" DG proposal execution state

# =======================================================================
# ==================== DG Proposal Submit => Execute ====================
# =======================================================================
# TODO (if DG proposal exists in vote) execute DG proposal
chain.sleep(timelock.getAfterSubmitDelay() + 1)
dual_governance.scheduleProposal(dg_proposal_id, {"from": stranger})
chain.sleep(timelock.getAfterScheduleDelay() + 1)
dg_tx: TransactionReceipt = timelock.execute(dg_proposal_id, {"from": stranger})

# =======================================================================
# ================= After DG proposal execution tests ===================
# =======================================================================
# TODO (if DG proposal exists in vote) run asserts that checks the "after" DG proposal execution state

# TODO (if DG proposal exists in vote) run DG proposal happy path tests

# =======================================================================
# ======================== IPFS & events checks =========================
# =======================================================================
# TODO check IPFS description
#metadata = find_metadata_by_vote_id(vote_id)
#assert get_lido_vote_cid_from_str(metadata) == "TODO <expected_ipfs_hash>"

# validate event count
evs = group_voting_events_from_receipt(vote_tx)
assert len(evs) == vote_events_count
assert count_vote_items_by_events(vote_tx, voting) == vote_events_count, "Incorrect voting items count"

# TODO validate all events emitted during the vote (check the event emitter as well!)

# TODO (if DG proposal exists in vote) validate all events emitted during the DG execution (check the event emitter as well!)
dg_evs = group_dg_events_from_receipt(dg_tx, timelock=EMERGENCY_PROTECTED_TIMELOCK, admin_executor=DUAL_GOVERNANCE_ADMIN_EXECUTOR)
Loading