Skip to content

Commit

Permalink
solana: enforce no fees have been charged
Browse files Browse the repository at this point in the history
we could support this case instead, but the calculation would be a
little more difficult on the client side
  • Loading branch information
kcsongor authored and johnsaigle committed Mar 19, 2024
1 parent aab0fb4 commit 0d764bf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions solana/programs/example-native-token-transfers/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ pub enum NTTError {
DisabledTransceiver,
#[msg("InvalidDeployer")]
InvalidDeployer,
#[msg("BadAmountAfterTransfer")]
BadAmountAfterTransfer,
#[msg("BadAmountAfterBurn")]
BadAmountAfterBurn,
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ pub fn transfer_burn(ctx: Context<TransferBurn>, args: TransferArgs) -> Result<(
accs.peer.token_decimals,
);

let before = accs.common.from.amount;

token_interface::burn(
CpiContext::new_with_signer(
accs.common.token_program.to_account_info(),
Expand All @@ -152,6 +154,13 @@ pub fn transfer_burn(ctx: Context<TransferBurn>, args: TransferArgs) -> Result<(
amount,
)?;

accs.common.from.reload()?;
let after = accs.common.from.amount;

if after != before - amount {
return Err(NTTError::BadAmountAfterBurn.into());
}

let recipient_ntt_manager = accs.peer.address;

insert_into_outbox(
Expand Down Expand Up @@ -227,6 +236,8 @@ pub fn transfer_lock(ctx: Context<TransferLock>, args: TransferArgs) -> Result<(
accs.peer.token_decimals,
);

let before = accs.custody.amount;

token_interface::transfer_checked(
CpiContext::new_with_signer(
accs.common.token_program.to_account_info(),
Expand All @@ -247,6 +258,21 @@ pub fn transfer_lock(ctx: Context<TransferLock>, args: TransferArgs) -> Result<(
accs.common.mint.decimals,
)?;

accs.custody.reload()?;
let after = accs.custody.amount;

// NOTE: we currently do not support tokens with fees. Support could be
// added, but it would require the client to calculate the amount _before_
// paying fees that results in an amount that can safely be trimmed.
// Otherwise, if the amount after paying fees has dust, then that amount
// would be lost.
// To support fee tokens, we would first transfer the amount, _then_ assert
// that the resulting amount has no dust (instead of removing dust before
// the transfer like we do now).
if after != before + amount {
return Err(NTTError::BadAmountAfterTransfer.into());
}

let recipient_ntt_manager = accs.peer.address;

insert_into_outbox(
Expand Down

0 comments on commit 0d764bf

Please sign in to comment.