-
Notifications
You must be signed in to change notification settings - Fork 30
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
STREAM-1597: account for transfer fees when creating Airdrops #177
STREAM-1597: account for transfer fees when creating Airdrops #177
Conversation
import { SignerWalletAdapter } from "@solana/wallet-adapter-base"; | ||
import { Connection, Keypair, PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js"; | ||
import { ContractError } from "@streamflow/common"; | ||
import { ConfirmationParams, signAndExecuteTransaction, ThrottleParams } from "@streamflow/common/solana"; | ||
|
||
import { fromTxError } from "./generated/errors"; | ||
import { ONE_IN_BASIS_POINTS } from "./constants"; | ||
|
||
export const divCeilN = (n: bigint, d: bigint): bigint => n / d + (n % d ? BigInt(1) : BigInt(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.
Since it's Friday, BigInt isn't as big as BN.
Also, BN has all of these operations.
I'll merge this and migrate it with staging so Milan can test it during the weekend, but let's fix this with BN asap :)
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.
BigInt is used in solana js-sdk, that's why we use it here.
const rawPreFeeAmount = divCeilN(numerator, denominator); | ||
const fee = rawPreFeeAmount - transferAmount; | ||
transferAmount = rawPreFeeAmount; | ||
feeCharged = fee > transferFee.maximumFee ? transferFee.maximumFee : fee; |
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.
Math.max()
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.
That's the max configured in Transfer Fee Config.
let feeCharged = BigInt(0); | ||
|
||
if (transferFeeBasisPoints !== BigInt(0)) { | ||
const numerator = transferAmount * ONE_IN_BASIS_POINTS; |
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.
Comment around this math would be helpful :)
When creating an Airdrop for mint with Transfer Fee extension we need to account for such fees, so that the Escrow has enough funds to distribute.
Logic loosely based on what we have in Rust Solana library https://github.com/solana-labs/solana-program-library/blob/master/token/program-2022/src/extension/transfer_fee/mod.rs#L90
Example transaction https://explorer.solana.com/tx/51qRMSAy8bXW93mGekBZZjQPv7zjja6Eibfab2j2RVKBSVFnn6Fo8qCap1CNPVWybKwQMfj12KpDyayqqwRRP2sU?cluster=devnet