Skip to content
This repository has been archived by the owner on Jan 10, 2025. It is now read-only.

Freeze Authorities for Token Swap/AMMs #1515

Closed
wants to merge 8 commits into from

Conversation

bhgames
Copy link

@bhgames bhgames commented Mar 29, 2021

As part of @bartosz-lipinski 's NFT project, this introduces Freeze Authorities for the Token Swap project and a bitmask that covers a toggle on-off switch for each of the actions available in the program. A freeze authority can be introduced on creation of a swap and then that signer (single sig only) can toggle on/off the bits with another action.

Couples with project-serum/oyster-swap#39

bhgames added 2 commits March 28, 2021 20:13
… save freeze authority via cloning. I like this situation better - no extra enum and hackiness required.
@bhgames bhgames marked this pull request as draft March 29, 2021 01:24
@bhgames bhgames marked this pull request as ready for review March 30, 2021 03:41
Copy link
Contributor

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of great stuff here! Mostly small comments to look at, but I'm liking the direction of this

@@ -83,6 +83,9 @@ export const TokenSwapLayout: typeof BufferLayout.Structure = BufferLayout.struc
Layout.uint64('hostFeeDenominator'),
BufferLayout.u8('curveType'),
BufferLayout.blob(32, 'curveParameters'),
BufferLayout.u32('freezeAuthorityOption'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a mixup of using a u8 in some parts for the Some/None COption and a u32 in the instructions. It looks like spl-token uses a u32, but I have no idea why. @CriesofCarrots I think you took care of this -- why does spl-token use a u32 for the option part of COption?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm not sure why he uses it. I just copied his pattern. The instructions seem to expect a u8 though, while the storage uses a u32.

Comment on lines +345 to +347
freezeAuthorityOption: 0,
freezeAuthority: undefined,
freezeAuthorityBitMask: 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll probably want to pass these into createInitSwapInstruction function instead of hard-coding

/// 2. process_withdraw_all_token_types,
/// 3. process_deposit_single_token_type_exact_amount_in,
/// 4. process_withdraw_single_token_type_exact_amount_out,
pub freeze_authority_bit_mask: u8,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight renaming

Suggested change
pub freeze_authority_bit_mask: u8,
pub frozen_operations_bit_mask: u8,

#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
#[repr(C)]
#[derive(Clone, Debug, PartialEq)]
pub struct SetFreezeAuthorityBitMask {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub struct SetFreezeAuthorityBitMask {
pub struct SetFrozenOperationsBitMask {

/// 2. process_withdraw_all_token_types,
/// 3. process_deposit_single_token_type_exact_amount_in,
/// 4. process_withdraw_single_token_type_exact_amount_out,
pub freeze_authority_bit_mask: u8,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub freeze_authority_bit_mask: u8,
pub frozen_operations_bit_mask: u8,

@@ -345,6 +391,7 @@ impl Processor {
return Err(ProgramError::IncorrectProgramId);
}
let token_swap = SwapVersion::unpack(&swap_info.data.borrow())?;
Self::check_allowed_to_use(token_swap.as_ref(), 0)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

take it or leave it, but a better alternative to hard-coding these bit numbers would be to use a true bitmask library. bitflags seems to be a pretty good one https://docs.rs/bitflags/1.2.1/bitflags/

let bitmask: u8 = token_swap.freeze_authority_bit_mask();
match Self::get_bit_at(bitmask, bit_position) {
Ok(frozen) => {
if frozen {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A newish best practice is to have a msg! explaining what's happening before throwing an error, which makes debugging from the explorer much easier. Swap isn't doing this everywhere of course, but this new code should 😄

/// Processes a [SetFreezeAuthorityBitMask](enum.Instruction.html).
pub fn process_set_freeze_authority_bit_mask(
_: &Pubkey,
freeze_authority_bit_mask: u8,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting a raw bitmask is fine, but be sure there's an easy library to do it from the outside!


Self::check_allowed_to_freeze(token_swap.as_ref(), freeze_authority_info)?;

let clone = SwapVersion::SwapV2(SwapV2 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can become brittle once we add a v3 -- could you deserialize it and set the new bitmask through a function? The v1 swap can error out for it

SwapError::UnauthorizedToFreeze => {
msg!("Error: Unauthorized to freeze")
}
SwapError::SwapV1UnsupportedAction => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something, but it doesn't seem like this is ever used

@@ -107,7 +131,8 @@ pub enum SwapInstruction {
/// Must be empty, not owned by swap authority
/// 6. `[writable]` Pool Token Account to deposit the initial pool token
/// supply. Must be empty, not owned by swap authority.
/// 7. '[]` Token program id
/// 7. '[]` Freeze authority. Optional.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't actually passed as an account, no need to have it as a comment

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops!

@joncinque
Copy link
Contributor

I was thinking about this some more, and you'll likely need an instruction to set the freeze authority as well, which takes in COption<Pubkey>, this way someone can set it to None to never have it changed ever again

@mergify mergify bot added the community Community contribution label Mar 28, 2023
@github-actions github-actions bot added the stale [bot only] Added to stale content; will be closed soon label Aug 10, 2023
@github-actions github-actions bot closed this Aug 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
community Community contribution stale [bot only] Added to stale content; will be closed soon
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants