Skip to content

farming-pool: no transfer_admin function — pool admin is permanently locked #16

Description

@prodbycorne

Overview

The factory contract has transfer_admin but the farming-pool contract has no equivalent. Once a pool is deployed, its admin address is immutable. This creates operational risks:

  • If the admin key is compromised, there is no recovery path — the pool must be abandoned
  • Governance handoffs (e.g., DAO multisig taking over) require redeploying the pool, losing all staker history
  • Factory's transfer_admin sets a precedent that admin rotation is expected, yet pool contracts don't support it

Required Change

Add transfer_admin to FarmingPool, mirroring the factory implementation:

/// Admin: transfer admin rights to . Current admin must authorise.
///
/// Emits a  event with .
pub fn transfer_admin(env: Env, new_admin: Address) -> Result<(), PoolError> {
    let current = get_admin(&env);
    current.require_auth();
    bump_instance(&env);

    env.storage().instance().set(&DataKey::Admin, &new_admin);

    env.events().publish(
        (symbol_short!("pool"), symbol_short!("adm_xfr")),
        (current, new_admin),
    );
    Ok(())
}

Also add a get_admin public read function (currently the admin address is only internally accessible):

pub fn admin(env: Env) -> Address {
    bump_instance(&env);
    get_admin(&env)
}

Acceptance Criteria

  • transfer_admin implemented on FarmingPool
  • admin() public getter added
  • Non-admin call to transfer_admin returns Err(PoolError::Unauthorized)
  • adm_xfr event emitted with old and new admin
  • After transfer, old admin can no longer call pause, set_global_multiplier, etc.
  • Test: full admin transfer flow
  • Test: original admin loses privileges after transfer

Metadata

Metadata

Assignees

No one assigned

    Labels

    farming-poolFarmingPool contractfeatureNew feature or capabilitysecuritySecurity vulnerability or hardening

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions