-
Notifications
You must be signed in to change notification settings - Fork 4
fix: fixed undelegation of ephemeral balance #76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…em program. Added new version of close_ephemeral_balance to support it. kept old one for backward-compatability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
10 file(s) reviewed, 5 comment(s)
Edit PR Review Bot Settings | Greptile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -45,7 +49,8 @@ impl DlpDiscriminator { | |||
impl TryFrom<[u8; 8]> for DlpDiscriminator { | |||
type Error = ProgramError; | |||
fn try_from(bytes: [u8; 8]) -> Result<Self, Self::Error> { | |||
match bytes[0] { | |||
let discriminator = u64::from_le_bytes(bytes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this more CU-intense without benefits (until the program reaches 255 instructions)?
|
||
use crate::discriminator::DlpDiscriminator; | ||
use crate::pda::ephemeral_balance_pda_from_payer; | ||
|
||
/// Creates instruction to close an ephemeral balance account | ||
/// See [crate::processor::process_close_ephemeral_balance] for docs. | ||
/// See [crate::processor::process_close_ephemeral_balance_v1] for docs. | ||
/// [crate::processor::process_close_ephemeral_balance] now deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably annotate process_close_ephemeral_balance
with #[deprecated(since="...", note="...")]
if ephemeral_balance_account.owner != &system_program::id() { | ||
msg!( | ||
"ephemeral balance expected to be owned by system program: {}", | ||
system_program::id() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be more interesting to log ephemeral_balance_account.owner
rather than the well-known system program. It might be even better to give a static message to avoid the CU cost of formatting strings
return Ok(()); | ||
} | ||
|
||
let ephemeral_balance_bump_slice: &[u8] = &[ephemeral_balance_bump]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it use close_pda
at some point like the old process_close_ephemeral_balance
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand this practically closes account, since it doesn't have lamports and data
@@ -56,7 +56,7 @@ pub fn process_top_up_ephemeral_balance( | |||
create_pda( | |||
ephemeral_balance_account, | |||
&system_program::id(), | |||
8, | |||
0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what causes this change in this PR (and the subsequent changes in tests), I'm guessing it's the core of the fix for something introduced in another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's 2 points to this
- It fixes undelegation. Otherwise we try to call non-existing callback
- I reckoned discriminator isn't needed. It is not set anyway. the account just stores lamports, the same as on curve addresses don't have any discriminator. The only thing that @GabrielePicco mentioned is that it might complicate filtering, but the address of this pda shall suffice for filtering
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was there mainly for consistency (discriminator should be set on creation) to allow queries such as getAllEscrowAccounts that are not otherwise possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see now what you meant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I'm missing something, I think there is a major problem with this implementation, the ER state is not committed before undelegating. Undelegation should always originate from a CPI executed as part of a transaction in the ER, and should go trough the normal commit/finalize flow, as otherwise the undelegation will revert the original balance
], | ||
data: [ | ||
DlpDiscriminator::CloseEphemeralBalance.to_vec(), | ||
DlpDiscriminator::CloseEphemeralBalanceV1.to_vec(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not currently used, so we can avoid the "V1" as it's not gonna be a breaking change
Problem
Ephemeral balance was undelegated to delegation program itslef. Expected behavior delegation to system program.
Solution
Introduced new method
undelegate_ephemeral_balance
that will callundelegate
and then reassign ownership tosystem_program
Before & After Screenshots
Insert screenshots of example code output
BEFORE:
[insert screenshot here]
AFTER:
[insert screenshot here]
Other changes (e.g. bug fixes, small refactors)
Added v1 for CloseEphemeralBalance. Reason is that this change shall be backwards-compatible. For exmaple, some users may have accounts undelegated using old logic, their lamports will be stuck if we remove old
CloseEphemeralBalance
.We keep only one version of CloseEphemeralBalance in InstructionBuilder utilities in order to enforce a newer logic. Clients may still recreate old instruction and call "v0" of
CloseEphemeralBalance
.Deploy Notes
Notes regarding deployment of the contained body of work. These should note any
new dependencies, new scripts, etc.
New scripts:
script
: script detailsNew dependencies:
dependency
: dependency detailsGreptile Summary
This PR fixes the undelegation of ephemeral balances by ensuring ownership is properly transferred to the system program instead of the delegation program.
src/instruction_builder/undelegate_ephemeral_balance.rs
to handle proper ownership reassignment to system program after undelegationCloseEphemeralBalanceV1
discriminator (0x10) while maintaining backward compatibility with v0 for existing accountstests/test_top_up.rs
to verify undelegation and closing functionalitysrc/processor/close_ephemeral_balance_v1.rs
to properly verify system program ownership and handle lamport transfersThe changes look well-structured with proper error handling and test coverage. The backward compatibility approach for CloseEphemeralBalance is appropriate to prevent breaking existing accounts.
💡 (5/5) You can turn off certain types of comments like style here!