Skip to content

GaugeWeightRouter

Phase 3 governance spine — translates GaugeController relative weights into Keep MultiStrategyVault allocation targets.

Source: khomdev-veforge/src/GaugeWeightRouter.vy (Vyper 0.4.x)

Dependencies: GaugeController · MultiStrategyVault

Implementation overview

  • Mapping — owner sets ordered gauge-per-strategy list matching vault.strategy_list
  • Poke — permissionless; reads live weights, normalizes to MAX_BPS - buffer_bps, calls set_allocations
  • Access — router holds vault ALLOCATOR_ROLE only (COMP-2); never moves funds
  • No-op — all-zero weights leaves allocations unchanged
flowchart LR
    GC[GaugeController] -->|gauge_relative_weight_write| GWR[GaugeWeightRouter]
    GWR -->|set_allocations| MSV[MultiStrategyVault]
    VE[Voters] -->|vote| GC

Immutables

Name Role
gauge_controller GaugeController
vault MultiStrategyVault

Constants

Name Value Role
MAX_STRATEGIES 10 Max mapped strategies
MAX_BPS 10000 Allocation denominator

Roles

Role Powers
owner (2-step) set_gauge_mapping
Anyone poke
Vault admin (separate) add_strategy, set_max_debt — not this router

Events

Event When
MappingUpdated Gauge mapping changed
Poked Allocations pushed to vault

Admin

set_gauge_mapping

GaugeWeightRouter.set_gauge_mapping(_gauges)

Set ordered gauge-per-strategy mapping. Order must match vault.strategy_list. Owner-only.

Param Type Description
_gauges DynArray[address, 10] Gauge address per strategy slot

Access: Owner only.

Events: MappingUpdated.

Reverts if: any entry is zero address.

Note: Length mismatch with live strategy list fails at pokeset_allocations (fail-closed).

Source (khomdev-veforge/src/GaugeWeightRouter.vy:111-128):

@external
def set_gauge_mapping(_gauges: DynArray[address, MAX_STRATEGIES]):
    ownable._check_owner()
    for i: uint256 in range(MAX_STRATEGIES):
        assert _gauges[i] != empty(address), "router: zero gauge"
    self.gauge_for_strategy = _gauges

Cross-links: poke · MultiStrategyVault.set_allocations

Apply

poke

GaugeWeightRouter.poke()

Permissionless. Pull live gauge weights, normalize to vault deployable BPS budget, push to set_allocations.

Access: Any caller. nonreentrant.

Events: Poked.

Reverts if: empty mapping or vault buffer_bps > MAX_BPS.

No-op when: all mapped gauges have zero relative weight.

Note: Uses gauge_relative_weight_write. Last slot absorbs floor-division dust so weights sum to deployable exactly.

Source (khomdev-veforge/src/GaugeWeightRouter.vy:133-191):

@external
@nonreentrant
def poke():
    w: uint256 = extcall IGaugeController(gauge_controller).gauge_relative_weight_write(
        self.gauge_for_strategy[i], block.timestamp,
    )
    deployable: uint256 = MAX_BPS - buffer
    # ... proportional split, last slot gets dust
    extcall IStrategyVault(vault).set_allocations(bps)
    log Poked(caller=msg.sender, deployable_bps=deployable, weights=bps)

Example:

gwr.poke()  # anyone can call after votes change

Cross-links: GaugeController.gauge_relative_weight_write · CoilMakerStrategy · MultiStrategyVault.rebalance