Relax Program Buffer Constraints
- Idea
- Draft
- Review
- Accept
- Implement
- Active
Decision brief
Why this proposal matters
This SIMD proposes relaxing current constraints on program buffers used by the DeployWithMaxDataLen (initial deployment) and Upgrade (redeployment) instructions, currently requiring them to: Be owned by BPFLoaderUpgradeab1e11111111111111111111111, and • Share an upgrade authority with the program being deployed or upgraded
Proposal at a glance
What changes
- No buffer authority signature is required.
- No buffer ownership check is required.
- The IncorrectAuthority check is removed:
Stakeholder map
Who is affected
Builders & client teams Medium impact
This change enables more flexible program deployment workflows, unlocking new use cases for developers. Some examples include:
Action requirement unknownValidators & operators Medium impact
This change enables more flexible program deployment workflows, unlocking new use cases for developers. Some examples include:
Action requirement unknownUsers & stakers Medium impact
Verified open-source deployments: Developers can publish verified builds of shared open-source program implementations as reusable buffers, allowing users who wish to fork the program to deploy it directly without building and uploading the binary themselves.
Action may be requiredGovernance & ecosystem Impact unknown
No proposal-specific evidence was found for this group.
Action requirement unknownExact source revision
Full proposal document
c9ec366af14dSummary
This SIMD proposes relaxing current constraints on program buffers used by the
DeployWithMaxDataLen (initial deployment) and Upgrade (redeployment)
instructions, currently requiring them to:
- Be owned by
BPFLoaderUpgradeab1e11111111111111111111111, and - Share an upgrade authority with the program being deployed or upgraded
Motivation
Currently, it is not feasible to support several advanced use cases for program buffers, including:
- Sponsored deployments
- Permissionless buffer reuse
- Retracting erroneous upgrades using a common buffer
- On-chain recompilation
By removing these constraints, the loader can support a broader range of advanced and flexible deployment workflows.
New Terminology
No new terminology is introduced by this proposal.
Detailed Design
The DeployWithMaxDataLen and Upgrade instructions will be updated to include
an optional close_buffer boolean input. If not provided, the default will
be true.
DeployWithMaxDataLen {
max_data_len: u64,
close_buffer: bool, // New
}
Upgrade {
close_buffer: bool, // New
}
The accounts required by the instructions are unchanged, but the signer
requirements differ based on the value of the close_buffer option.
For a value of true, existing behavior is preserved. The buffer account will
be closed (lamports transferred to a designated recipient and account data
zeroed).
For a value of false, the buffer account is not modified, enabling reuse for
future deployments. Since the buffer is not closed, its lamports are not
transferred to the spill account. Instead, the program data account must
already contain sufficient lamports to satisfy rent requirements. In practice,
this means the deployer or upgrader must pre-fund the program data account
(e.g. via a transfer in a preceding instruction) before invoking the deploy or
upgrade. The net rent cost to the end user remains the same as in the
close_buffer=true case, since the user did not pay for the buffer.
Additionally, constraints on the buffer are relaxed:
- No buffer authority signature is required.
- No buffer ownership check is required.
- The
IncorrectAuthoritycheck is removed:DeployWithMaxDataLen: The buffer's authority no longer must match the authority that will be set on the deployed program.Upgrade: The buffer's authority no longer must match the upgrade authority stored on the program account.
Note that the program's authority account must still be provided in the same
position for both instructions and must still sign the transaction. Only the
buffer-related checks are relaxed for close_buffer=false; the
MissingRequiredSignature check for the program's authority remains enforced.
DeployWithMaxDataLen / Upgrade { close_buffer }
|
+-----------+-----------+
| |
close_buffer=true close_buffer=false
(default) |
| Relaxed buffer checks
Existing checks Buffer not modified
Buffer closed (reusable)
Buffer Layout Requirement
Regardless of the buffer's owner, the buffer account must still conform to the
expected layout for Loader V3 buffer accounts. Specifically, the account data
must deserialize to UpgradeableLoaderState::Buffer (discriminant 1 as a
little-endian u32), and the ELF data must begin at the expected offset within
the account data (after the header).
| discriminant (4 bytes) | authority_address (33 bytes) | ELF data ... |
| 0x01000000 | option byte + pubkey | |
| | | |
|<--------------- 37-byte header ---------------------->|
Alternatives Considered
- Introduce a new loader that enables these behaviors by default
- Only relax the authority constraint (similar outcome, but requires CPI)
- Retain existing constraints and make no changes
Impact
This change enables more flexible program deployment workflows, unlocking new use cases for developers. Some examples include:
- Emergency abort programs: Protocols under attack can deploy an emergency abort program from a pre-staged buffer to immediately halt all flows through their program, without needing to prepare a buffer during the incident.
- Verified open-source deployments: Developers can publish verified builds of shared open-source program implementations as reusable buffers, allowing users who wish to fork the program to deploy it directly without building and uploading the binary themselves.
- Education and onboarding: Education centers can make buffers available for programs used in lesson plans, so students can easily deploy necessary components to test their implementations on higher networks (e.g. devnet, mainnet-beta).
Security Considerations
This proposal introduces two new, strictly opt-in potential attack vectors:
- In multisig deployment flows (e.g., Squads), if a quorum authorizes an upgrade using a buffer it does not own, the buffer could be modified by a third party prior to deployment. This introduces additional security considerations beyond those enforced by the multisig quorum itself.
- If a buffer is owned by a third-party program, that program may retain write access to the buffer account irrespective of its upgrade authority. This creates a potential supply chain attack vector if the security assumptions of the owner program are not carefully evaluated.
Backwards Compatibility
This feature relaxes existing Loader V3 constraints and is therefore not backwards compatible for consensus, necessitating a feature gate. For CLI and tooling, the change is fully backwards compatible.
Evidence graph
Related proposals and rollout
One or more sources are unavailable.
Upstream review record
Upstream discussion & review
GitHub review is editorial context, not evidence of on-chain support, voting, or outcome.
PR #430 · merged SIMD-0430: Loader V3: Relax Program Buffer Constraints 41 comments and reviews · Apr 16, 2026We're pretty set on not adding additional instructions, but if you have some opinions about the final implementation of the changes to the instruction, such as serialization or whatever, perhaps we can take this discussion to the PR itself? Yep, that's fine by me
GitHub ↗We're pretty set on not adding additional instructions, but if you have some opinions about the final implementation of the changes to the instruction, such as serialization or whatever, perhaps we can take this discussion to the PR itself? Unfortunately, if the implementation is going to be blocked on whether we use new variants or input parameters, we'll have to iron that out here so that it's reflected in the spec. We've historically modeled program instructions after what bincode supports. However, I've hacked up a simple version of the loader-v3-interface that doesn't use bincode or bytemuck and instead just does everything by hand. I'm sure @deanmlittle could be nerd-sniped into iterat
GitHub ↗To simplify my point: why do something complicated when we can do something simple? If we have to hand-write parsers, we've already lost, since libraries and frameworks should be able to generate these wherever possible. Of course, in some cases we need more complicated approaches, but that's not the case here.
GitHub ↗Unfortunately, if the implementation is going to be blocked on whether we use new variants or input parameters, we'll have to iron that out here so that it's reflected in the spec. I agree that would be the case, but is that what's happening here? We had this out in Abu Dhabi where we stressed the importance of trying to maintain backwards compatibility whilst unlocking more flexibility in the existing instructions. This SIMD has been live for 4 months and we have had it out already, but still collectively decided on extending the input parameters. Is there a good reason why we're reviewing this again now? We've historically modeled program instructions after what bincode supports. The great
GitHub ↗If we have to hand-write parsers, we've already lost, since libraries and frameworks should be able to generate these wherever possible. Simplicity.jpg
GitHub ↗To simplify my point: why do something complicated when we can do something simple? I'm not really convinced the design is complicated, though. If we have to hand-write parsers, we've already lost, since libraries and frameworks should be able to generate these wherever possible. It's not really that we have to, I'm just demonstrating that the only reason my SDK PR looks outrageous is because we've been married to bincode. There are probably tools that handle this just fine, without hand-rolling.
GitHub ↗There are probably tools that handle this just fine, without hand-rolling. Every serialization library handles my suggestion with zero work. It also allows for zero-copy on instruction data with no other weirdness. It's a nit, so I don't want to blow this out of proportion, but also, no one has concretely responded to my comments. If the real response is "I don't care", that's a bit unsatisfying, but also a valid response to a nit.
GitHub ↗It's a nit, so I don't want to blow this out of proportion, but also, no one has concretely responded to my comments. If the real response is "I don't care", that's a bit unsatisfying, but also a valid response to a nit. Concretely I think the proposal as written and approved is a completely valid way to implement the toggle behavior and I prefer it over awkwardly adding new variants which dispatch to the same instruction but toggle one subroutine. If it's really just a nit, and there isn't a critical reason we can't continue with this implementation, I am in favor of proceeding. Surprisingly, Loader V3 actually doesn't have such duplicated variants as of yet. Even ExtendProgramChecked would
GitHub ↗Provenance
Evidence & technical details
Rollout or chain data, source revisions, freshness and integrity. 2
Provenance
Evidence & technical details
Rollout or chain data, source revisions, freshness and integrity.SIMD
Deployment Status
H5AgGhTzvHp2GH9SVGZYBpjeQPy1V9bqYQ4MmTtiCWr9Exact source revision
Sources & integrity
- Proposal document pinned_commit_blob
c9ec366af14dd32a74259f5d9f5772249188bd25 - simd-document document · stale · Oct 26, 2026
c9ec366af14dd32a74259f5d9f5772249188bd25
One or more sources are unavailable.
simd.watch community discussion · SIMD-0430
Powered by Giscus · Sign in with GitHub to comment
Community comments load when this section approaches the viewport.