Skip to content

Closing a YieldVault can leave a stale scheduled AutoBalancer tx that later fails with Invalid transaction handler #235

@liobrasil

Description

@liobrasil

Summary

Closing a YieldVault can leave behind an already-scheduled DeFiActions.AutoBalancer transaction. When that stale scheduled tx later executes, FlowTransactionScheduler fails with:

Invalid transaction handler: Could not borrow a reference to the transaction handler

This happened on mainnet for YieldVault 338.

On-chain sequence

  1. 2026-03-26 15:59:29 UTC
    Tx cebd06599a069af88b3ceb909b4fdadaa32d366cd4c7b72c48c9aca841ecb8b3

    • FYVEVM worker created YieldVault 338
    • same tx emitted DeFiActions.CreatedAutoBalancer with uuid = 13194142095838, uniqueID = 338
    • same tx emitted FlowTransactionScheduler.Scheduled with:
      • id = 156720
      • transactionHandlerTypeIdentifier = A.6d888f175c158410.DeFiActions.AutoBalancer
      • transactionHandlerUUID = 13194142095838
      • timestamp = 2026-03-26 16:09:29 UTC
  2. 2026-03-26 16:02:28 UTC
    Tx ccd2722170525c1bd7ece82dc50b71f899ea7e85324e8d2e78c482c64ab35087

    • FYVEVM scheduler picked up close request 97 for YieldVault 338
    • scheduled worker tx 156723
  3. 2026-03-26 16:02:29 UTC
    Tx 53d2d8169a77851b1a729e19cd2e39642e1ed20519cd14c07ac4eff307f24b71

    • FYVEVM worker closed YieldVault 338 successfully
  4. 2026-03-26 16:09:29 UTC
    Tx 2a6a879ca2049edca43dc7392fbe5f3420550366452117a41e90686335eece3e

    • generic scheduler wrapper attempted to execute scheduled tx 156720
    • failed with Invalid transaction handler: Could not borrow a reference to the transaction handler

Why this looks like a FlowYieldVaults cleanup bug

The scheduled tx 156720 is clearly the AutoBalancer tx created for YieldVault 338. But vault 338 was already closed about 7 minutes earlier, so when 156720 fired, its handler no longer existed.

From the deployed mainnet contracts:

  • FlowYieldVaultsStrategiesV2.burnCallback() calls FlowYieldVaultsAutoBalancers._cleanupAutoBalancer(id: self.id()!)
  • _cleanupAutoBalancer() unregisters the vault, deletes capability controllers, and burns the AutoBalancer
  • FlowYieldVaultsSchedulerRegistry.unregister() removes registry/capability mappings but does not cancel already-scheduled transactions
  • DeFiActions.AutoBalancer does have cancelScheduledTransaction, but AutoBalancer.burnCallback() does not cancel outstanding scheduled txs

So the close path appears to remove the AutoBalancer handler without first canceling its already-scheduled rebalance txs.

Expected behavior

When a YieldVault is closed, any pending AutoBalancer scheduled transactions for that vault should be canceled before the AutoBalancer handler/capabilities are removed.

Actual behavior

The AutoBalancer handler is cleaned up, but the already-scheduled transaction remains in FlowTransactionScheduler and later fails at execution time.

Additional note

The docs currently state that closing a YieldVault cancels pending schedules, but the observed mainnet behavior above shows that at least this path still leaves a stale scheduled tx behind.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions