feat: add support for owner/host fees

This commit is contained in:
bartosz-lipinski 2021-01-06 11:06:32 -06:00
parent 1177d94153
commit f3608c37d4
6 changed files with 53 additions and 22 deletions

5
.env Normal file
View File

@ -0,0 +1,5 @@
# HOST Public Key used for additional swap fees
LEND_HOST_FEE_ADDRESS=''
# Rewired variables to comply with CRA restrictions
REACT_APP_LEND_HOST_FEE_ADDRESS=$LEND_HOST_FEE_ADDRESS

View File

@ -8,7 +8,7 @@ import { sendTransaction } from "../contexts/connection";
import { notify } from "../utils/notifications";
import { LendingReserve } from "./../models/lending/reserve";
import { AccountLayout, MintInfo, MintLayout } from "@solana/spl-token";
import { LENDING_PROGRAM_ID } from "../utils/ids";
import { LENDING_PROGRAM_ID, LEND_HOST_FEE_ADDRESS } from "../utils/ids";
import {
createTempMemoryAccount,
createUninitializedAccount,
@ -60,20 +60,20 @@ export const borrow = async (
const obligation = existingObligation
? existingObligation.pubkey
: createUninitializedObligation(
instructions,
wallet.publicKey,
await connection.getMinimumBalanceForRentExemption(LendingObligationLayout.span),
signers
);
instructions,
wallet.publicKey,
await connection.getMinimumBalanceForRentExemption(LendingObligationLayout.span),
signers
);
const obligationMint = existingObligation
? existingObligation.info.tokenMint
: createUninitializedMint(
instructions,
wallet.publicKey,
await connection.getMinimumBalanceForRentExemption(MintLayout.span),
signers
);
instructions,
wallet.publicKey,
await connection.getMinimumBalanceForRentExemption(MintLayout.span),
signers
);
const obligationTokenOutput = obligationAccount
? obligationAccount
@ -172,6 +172,19 @@ export const borrow = async (
const memory = createTempMemoryAccount(instructions, wallet.publicKey, signers);
// Creates host fee account if it doesn't exsist
let hostFeeReceiver = LEND_HOST_FEE_ADDRESS
? findOrCreateAccountByMint(
wallet.publicKey,
LEND_HOST_FEE_ADDRESS,
instructions,
cleanupInstructions,
accountRentExempt,
depositReserve.info.collateralMint,
signers
)
: undefined;
// deposit
instructions.push(
borrowInstruction(
@ -181,6 +194,8 @@ export const borrow = async (
toAccount,
depositReserve.pubkey,
depositReserve.info.collateralSupply,
depositReserve.info.collateralFeesReceiver,
borrowReserve.pubkey,
borrowReserve.info.liquiditySupply,
@ -196,7 +211,9 @@ export const borrow = async (
dexMarketAddress,
dexOrderBookSide,
memory
memory,
hostFeeReceiver,
)
);
try {

View File

@ -7,7 +7,7 @@ import { PoolInfo, TokenAccount } from './../models';
import { chunks } from './../utils/utils';
import { EventEmitter } from './../utils/eventEmitter';
import { useUserAccounts } from '../hooks/useUserAccounts';
import { WRAPPED_SOL_MINT, programIds } from '../utils/ids';
import { WRAPPED_SOL_MINT, programIds, LEND_HOST_FEE_ADDRESS } from '../utils/ids';
const AccountsContext = React.createContext<any>(null);
@ -382,6 +382,8 @@ export function AccountsProvider({ children = null as any }) {
if (!connection || !publicKey) {
setTokenAccounts([]);
} else {
precacheUserTokenAccounts(connection, LEND_HOST_FEE_ADDRESS);
precacheUserTokenAccounts(connection, publicKey).then(() => {
setTokenAccounts(selectUserAccounts());
});

View File

@ -41,6 +41,8 @@ export const borrowInstruction = (
to: PublicKey, // Liquidity output SPL Token account,
depositReserve: PublicKey,
depositReserveCollateralSupply: PublicKey,
ownerFeeReceiver: PublicKey,
borrowReserve: PublicKey,
borrowReserveLiquiditySupply: PublicKey,
@ -56,7 +58,9 @@ export const borrowInstruction = (
dexMarket: PublicKey,
dexOrderBookSide: PublicKey,
memory: PublicKey
memory: PublicKey,
hostFeeReceiver?: PublicKey,
): TransactionInstruction => {
const dataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
@ -83,6 +87,8 @@ export const borrowInstruction = (
isSigner: false,
isWritable: true,
},
{ pubkey: ownerFeeReceiver, isSigner: false, isWritable: false },
{ pubkey: borrowReserve, isSigner: false, isWritable: true },
{
pubkey: borrowReserveLiquiditySupply,
@ -105,6 +111,11 @@ export const borrowInstruction = (
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
];
if(hostFeeReceiver) {
keys.push({ pubkey: hostFeeReceiver, isSigner: false, isWritable: false })
}
return new TransactionInstruction({
keys,
programId: LENDING_PROGRAM_ID,

View File

@ -7,7 +7,6 @@ import {
} from '@solana/web3.js';
import BN from 'bn.js';
import * as BufferLayout from 'buffer-layout';
import { HALF_WAD } from '../../constants';
import { TOKEN_PROGRAM_ID, LENDING_PROGRAM_ID } from '../../utils/ids';
import { wadToLamports } from '../../utils/utils';
import * as Layout from './../../utils/layout';

View File

@ -10,17 +10,14 @@ let SWAP_PROGRAM_ID: PublicKey;
let SWAP_PROGRAM_LEGACY_IDS: PublicKey[];
let SWAP_PROGRAM_LAYOUT: any;
export const SWAP_PROGRAM_OWNER_FEE_ADDRESS = new PublicKey('HfoTxFR1Tm6kGmWgYWD6J7YHVy1UwqSULUGVLXkJqaKN');
export const LEND_HOST_FEE_ADDRESS = process.env.REACT_APP_LEND_HOST_FEE_ADDRESS
? new PublicKey(`${process.env.REACT_APP_LEND_HOST_FEE_ADDRESS}`)
: undefined;
export const SWAP_HOST_FEE_ADDRESS = process.env.REACT_APP_SWAP_HOST_FEE_ADDRESS
? new PublicKey(`${process.env.REACT_APP_SWAP_HOST_FEE_ADDRESS}`)
: SWAP_PROGRAM_OWNER_FEE_ADDRESS;
console.debug(`Lend host fee address: ${LEND_HOST_FEE_ADDRESS?.toBase58()}`);
export const ENABLE_FEES_INPUT = false;
console.debug(`Host address: ${SWAP_HOST_FEE_ADDRESS?.toBase58()}`);
console.debug(`Owner address: ${SWAP_PROGRAM_OWNER_FEE_ADDRESS?.toBase58()}`);
// legacy pools are used to show users contributions in those pools to allow for withdrawals of funds
export const PROGRAM_IDS = [
{