@shogun-sdk/money-legos
Version:
Shogun Money Legos: clients and types for quotes, memes, prices, balances, fees, validations, etc.
114 lines (97 loc) • 3.53 kB
text/typescript
import { CHAIN_MAP } from '../config/chains.js';
import { STABLECOINS } from '../config/stablecoins.js';
import { compareAddresses, isNativeToken } from './address.js';
import { AffiliateFeeData, FormattedAffiliateFee } from '../types/affiliateFees.js';
import { CallStruct } from '../types/multicall.js';
import { sendERC20Tokens } from './encoding.js';
import { sendNativeTokens } from './encoding.js';
export interface PrepareAffiliateFeeParams {
srcToken: string;
destToken: string;
srcChainId: number;
destChainId: number;
}
// true if we need to exclude affiliate fee
export const excludeAffiliateFee = ({ srcToken, destToken, srcChainId, destChainId }: PrepareAffiliateFeeParams) => {
// true if we need to exclude affiliate fee
if (!srcChainId || !destChainId) {
return false;
}
const srcChain = CHAIN_MAP[srcChainId];
const destChain = CHAIN_MAP[destChainId];
if (!srcChain || !destChain) {
return false;
}
if (!srcToken || !destToken) {
return false;
}
// Case 1: Cross-chain swap and both src and dest are native assets
if (srcChainId !== destChainId && isNativeToken(srcToken) && isNativeToken(destToken)) {
return true;
}
// Case 2: src asset is native and dest asset is USDC (or vice versa)
const srcIsNative = isNativeToken(srcToken);
const destIsNative = isNativeToken(destToken);
const srcIsUSD =
STABLECOINS[srcChainId]?.USDC?.address &&
STABLECOINS[srcChainId]?.USDT?.address &&
(compareAddresses(srcToken, STABLECOINS[srcChainId]?.USDC?.address) ||
compareAddresses(srcToken, STABLECOINS[srcChainId]?.USDT?.address));
const destIsUSD =
STABLECOINS[destChainId]?.USDC?.address &&
STABLECOINS[destChainId]?.USDT?.address &&
(compareAddresses(destToken, STABLECOINS[destChainId]?.USDC?.address) ||
compareAddresses(destToken, STABLECOINS[destChainId]?.USDT?.address));
if ((srcIsNative && destIsUSD) || (srcIsUSD && destIsNative)) {
return true;
}
// Case 3: Both src and dest are USDC (any chain)
if (srcIsUSD && destIsUSD) {
return true;
}
return false;
};
/**
* Calculates fee amount based on base amount and fee percent
* @param feePercent Fee percent %
* @param baseAmount Base amount to take fees from
*/
export function getFeeAmount(feePercent: number, baseAmount: bigint): bigint {
return (baseAmount * BigInt(Math.round(feePercent * 10_000_000_000))) / 1000_000_000_000n;
}
/**
* Formats affiliate fee data for query response
* @param affiliateFeeData Affiliate fee data
* @param config Trade config
*/
export function formatAffiliateData(
affiliateFeeData: AffiliateFeeData,
config: { affiliateWallet: string },
): FormattedAffiliateFee {
return {
affiliateFee: {
receiver: config.affiliateWallet as `0x${string}`,
feeToken: affiliateFeeData.feeToken,
feeAmount: affiliateFeeData.feeAmount.toString(),
},
};
}
/**
* Generate call to transfer Token to affiliate wallet
* @param feeAmount Amount of fee tokens to collect
* @param affiliateWallet Affiliate wallet address
* @param tokenAddress Token address that needs to be transferred
* @param nativeToken `true` - Token OUT is native token
*/
export function getTransferTokenFeeCall(
feeAmount: bigint,
affiliateWallet: `0x${string}`,
tokenAddress: `0x${string}`,
nativeToken: boolean,
): CallStruct {
if (nativeToken) {
return sendNativeTokens(feeAmount, affiliateWallet);
} else {
return sendERC20Tokens(tokenAddress, feeAmount, affiliateWallet);
}
}