BalancerMaxis/multisig-ops

Gauge Offboarding Automation

Opened this issue · 1 comments

Gauge Offboarding Automation a.k.a. identifying stale gauges to kill

Motivation

Given the insights gathered in the Gauge Framework Status Report we want to develop a job or routine that frequently checks all gauges and identifies candidates that did not receive veBAL votes for a longer time period (tbd)

Technical Specification

An ideal solution consists of a cron job that triggers a report in the multi-sig or other repo to evaluate all currently active gauges on all networks and returns a report incl. a payload that can be prepared for governance. The requirements are:

  • Exeuction time: fee-sweep off week (non-odd week number)
  • Output table with human readable overview
  • Payload

Components

  • General configuration file that can be used to easily adjust settings such as 'time until gauge is stale', e.g. 3 months
  • Python job / routine checking historical voting, most likely hosted in the bal_addresses repository
  • Automation job to create a report / table, ideally with a layout similar to this:
    | Chain | Pool Name | Root Gauge | Child Chain Gauge | Last Voting Epoch |
    |----------|--------------|------------|-------------------|-------------------|
    | Ethereum | sToken:WETH | 0x123 | 0x123 | 2023-01-05 |
    | Ethereum | Placeholder1 | 0xabc | 0xdef | 2023-02-15 |
    | Ethereum | Placeholder2 | 0x456 | 0x789 | 2023-03-10 |
    | Ethereum | Placeholder3 | 0xabcde | 0xfghij | 2023-04-20 |
  • Payload builder that creates a kill gauge payload. Can use this as a reference: https://defilytica.tools/#/balancer/payloadBuilder

Implementation Details

  1. Obtain global gauge list, incl. already killed ones from api-v3 with this query:
query VeBalGetVotingGauges {
    veBalGetVotingList
    {
        id
        address
        chain
        type
        symbol
        gauge {
            address
            isKilled
            relativeWeightCap
            addedTimestamp
        }
        tokens {
            address
            logoURI
            symbol
            weight
        }
    }
}
  1. Obtain the currently active set where isKilled flag is false
  2. For each non-killed gauge, obtain the voting history from on-chain events or another source (see additional information)
  3. For a given threshold (tbd, e.g. 3 months) obtain the set of gauges to be killed
  4. Make sure that newly added gauges are not picked up -> check addedTimestamp (alternatively on-chain events from gauge adder v4)?
  5. generate output table
  6. generate paylaod
  7. generate PR
    Make sure to handle cases where no gauge has been identified

Additional information

It is important to note that the balancer-gauges subgraph does not contain any information about historical votes. Therefore, we need to develop an on-chain solution or use available infrastructure from Dune to obtain that data.

Governance process

  • The Balancer Maxis will act as final reviewers of this automation.
  • The Maxis will also improve the current governance process so that partners whose gauges are up for kills shall have enough time to react and provide input

As per Fabio following approaches can be taken to obtain historical voting weights:

on Dune we have this view balancer_ethereum.vebal_votes whose schema is: round, provider, gauge, votes. Then if you aggregate it you find historical votes by gauges. I'm not sure if you're fine querying that data from somewhere or you want to re-build it in Python. if (1) you could use [Dune API and their Python SDK](https://docs.dune.com/api-reference/overview/sdks) and if (2) you'd need to get all gauges from API or Subgraph, get all end-of-round timestamps, call gauge relative weight(gauge, ts) for each gauge and round from Controller contract - quite RPC intensive but you don't have to re-implement logic in Python