From c93805a0ce4e3e40e84d30c94c5a734f0d5245ce Mon Sep 17 00:00:00 2001 From: Jarett Dunn Date: Thu, 27 Oct 2022 12:27:24 -0300 Subject: [PATCH 1/5] she builds; welcome to suggestion. --- airdrop.sh | 9 ++++ deploy_token_lending.sh | 70 ++++++++------------------ token-lending/program/src/processor.rs | 15 ++++++ yarn.lock | 4 ++ 4 files changed, 48 insertions(+), 50 deletions(-) create mode 100644 airdrop.sh create mode 100644 yarn.lock diff --git a/airdrop.sh b/airdrop.sh new file mode 100644 index 00000000000..f272dd9ee79 --- /dev/null +++ b/airdrop.sh @@ -0,0 +1,9 @@ +while : + +do + +solana airdrop 1 + +sleep 4 + +done diff --git a/deploy_token_lending.sh b/deploy_token_lending.sh index 387fd812fb2..a72f7404454 100755 --- a/deploy_token_lending.sh +++ b/deploy_token_lending.sh @@ -6,7 +6,7 @@ PROGRAM_ID=$2; OWNER=`grep 'keypair_path:' $SOLANA_CONFIG | awk '{print $2}'`; MARKET_OWNER=`solana --config $SOLANA_CONFIG address`; -target/debug/spl-token --config $SOLANA_CONFIG unwrap; +spl-token --config $SOLANA_CONFIG unwrap; set -e; echo "Using Solana config filepath: $SOLANA_CONFIG"; @@ -14,17 +14,16 @@ echo "Program ID: $PROGRAM_ID"; echo "Owner: $OWNER"; echo "Market Owner $MARKET_OWNER"; -solana config set --url https://api.devnet.solana.com; +solana config set --url https://solana-devnet.g.alchemy.com/v2/4Q5FSmnGz3snzIr01s-ZNwAtdFdnDB9L; -solana airdrop 10 $MARKET_OWNER; -SOURCE=`target/debug/spl-token --config $SOLANA_CONFIG wrap 10 2>&1 | head -n1 | awk '{print $NF}'`; +SOURCE=`spl-token --config $SOLANA_CONFIG wrap 1 2>&1 | head -n1 | awk '{print $NF}'`; solana program --config $SOLANA_CONFIG deploy \ --program-id $PROGRAM_ID \ target/deploy/solend_program.so; echo "Creating Lending Market"; -CREATE_MARKET_OUTPUT=`target/debug/solend-program create-market \ +CREATE_MARKET_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID create-market \ --fee-payer $OWNER \ --market-owner $MARKET_OWNER \ --verbose`; @@ -33,37 +32,15 @@ echo "$CREATE_MARKET_OUTPUT"; MARKET_ADDR=`echo $CREATE_MARKET_OUTPUT | head -n1 | awk '{print $4}'`; AUTHORITY_ADDR=`echo $CREATE_MARKET_OUTPUT | grep "Authority Address" | awk '{print $NF}'`; -echo "Creating SOL reserve"; -SOL_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ - --fee-payer $OWNER \ - --market-owner $OWNER \ - --source-owner $OWNER \ - --market $MARKET_ADDR \ - --source $SOURCE \ - --amount 5 \ - --pyth-product 3Mnn2fX6rQyUsyELYms1sBJyChWofzSNRoqYzvgMVz5E \ - --pyth-price J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix \ - --switchboard-feed AdtRGGhmqvom3Jemp5YNrxd9q9unX36BZk1pujkkXijL \ - --optimal-utilization-rate 80 \ - --loan-to-value-ratio 75 \ - --liquidation-bonus 5 \ - --liquidation-threshold 80 \ - --min-borrow-rate 0 \ - --optimal-borrow-rate 12 \ - --max-borrow-rate 150 \ - --host-fee-percentage 50 \ - --deposit-limit 40000 \ - --verbose`; -echo "$SOL_RESERVE_OUTPUT"; # USDC Reserve echo "Creating USDC Reserve"; -USDC_TOKEN_MINT=`target/debug/spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; +USDC_TOKEN_MINT=`spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; echo "USDC MINT: $USDC_TOKEN_MINT" -USDC_TOKEN_ACCOUNT=`target/debug/spl-token --config $SOLANA_CONFIG create-account $USDC_TOKEN_MINT | awk '{print $3}'`; -target/debug/spl-token --config $SOLANA_CONFIG mint $USDC_TOKEN_MINT 30000000; +USDC_TOKEN_ACCOUNT=`spl-token --config $SOLANA_CONFIG create-account $USDC_TOKEN_MINT | awk '{print $3}'`; +spl-token --config $SOLANA_CONFIG mint $USDC_TOKEN_MINT 30000000; -USDC_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ +USDC_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-reserve \ --fee-payer $OWNER \ --market-owner $OWNER \ --source-owner $OWNER \ @@ -81,18 +58,18 @@ USDC_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ --optimal-borrow-rate 8 \ --max-borrow-rate 50 \ --host-fee-percentage 50 \ - --deposit-limit 1000000 \ + --deposit-limit 1000000 --protocol-take-rate 1 --protocol-liquidation-fee 1 \ --verbose`; echo "$USDC_RESERVE_OUTPUT"; # ETH Reserve echo "Creating ETH Reserve" -ETH_TOKEN_MINT=`target/debug/spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; +ETH_TOKEN_MINT=`spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; echo "ETH MINT: $ETH_TOKEN_MINT" -ETH_TOKEN_ACCOUNT=`target/debug/spl-token --config $SOLANA_CONFIG create-account $ETH_TOKEN_MINT | awk '{print $3}'`; -target/debug/spl-token --config $SOLANA_CONFIG mint $ETH_TOKEN_MINT 8000000; +ETH_TOKEN_ACCOUNT=`spl-token --config $SOLANA_CONFIG create-account $ETH_TOKEN_MINT | awk '{print $3}'`; +spl-token --config $SOLANA_CONFIG mint $ETH_TOKEN_MINT 8000000; -ETH_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ +ETH_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-reserve \ --fee-payer $OWNER \ --market-owner $OWNER \ --source-owner $OWNER \ @@ -110,18 +87,18 @@ ETH_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ --optimal-borrow-rate 8 \ --max-borrow-rate 100 \ --host-fee-percentage 50 \ - --deposit-limit 500 \ + --deposit-limit 500 --protocol-take-rate 1 --protocol-liquidation-fee 1 \ --verbose`; echo "$ETH_RESERVE_OUTPUT"; echo "Creating BTC Reserve" -BTC_TOKEN_MINT=`target/debug/spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; +BTC_TOKEN_MINT=`spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; echo "BTC MINT: $BTC_TOKEN_MINT" -BTC_TOKEN_ACCOUNT=`target/debug/spl-token --config $SOLANA_CONFIG create-account $BTC_TOKEN_MINT | awk '{print $3}'`; -target/debug/spl-token --config $SOLANA_CONFIG mint $BTC_TOKEN_MINT 8000000; +BTC_TOKEN_ACCOUNT=`spl-token --config $SOLANA_CONFIG create-account $BTC_TOKEN_MINT | awk '{print $3}'`; +spl-token --config $SOLANA_CONFIG mint $BTC_TOKEN_MINT 8000000; -BTC_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ +BTC_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-reserve \ --fee-payer $OWNER \ --market-owner $OWNER \ --source-owner $OWNER \ @@ -139,11 +116,11 @@ BTC_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ --optimal-borrow-rate 8 \ --max-borrow-rate 100 \ --host-fee-percentage 50 \ - --deposit-limit 30 \ + --deposit-limit 30 --protocol-take-rate 1 --protocol-liquidation-fee 1 \ --verbose`; echo "$BTC_RESERVE_OUTPUT"; -target/debug/spl-token --config $SOLANA_CONFIG unwrap; +spl-token --config $SOLANA_CONFIG unwrap; # Export variables for new config.ts file CONFIG_TEMPLATE_FILE="https://raw.githubusercontent.com/solendprotocol/common/master/src/devnet_template.json" @@ -156,13 +133,6 @@ export BTC_MINT_ADDRESS="$BTC_TOKEN_MINT"; export MAIN_MARKET_ADDRESS="$MARKET_ADDR"; export MAIN_MARKET_AUTHORITY_ADDRESS="$AUTHORITY_ADDR"; -# Reserves -export SOL_RESERVE_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding reserve" | awk '{print $NF}'`; -export SOL_RESERVE_COLLATERAL_MINT_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding collateral mint" | awk '{print $NF}'`; -export SOL_RESERVE_COLLATERAL_SUPPLY_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding collateral supply" | awk '{print $NF}'`; -export SOL_RESERVE_LIQUIDITY_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding liquidity supply" | awk '{print $NF}'`; -export SOL_RESERVE_LIQUIDITY_FEE_RECEIVER_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding liquidity fee receiver" | awk '{print $NF}'`; - export USDC_RESERVE_ADDRESS=`echo "$USDC_RESERVE_OUTPUT" | grep "Adding reserve" | awk '{print $NF}'`; export USDC_RESERVE_COLLATERAL_MINT_ADDRESS=`echo "$USDC_RESERVE_OUTPUT" | grep "Adding collateral mint" | awk '{print $NF}'`; export USDC_RESERVE_COLLATERAL_SUPPLY_ADDRESS=`echo "$USDC_RESERVE_OUTPUT" | grep "Adding collateral supply" | awk '{print $NF}'`; diff --git a/token-lending/program/src/processor.rs b/token-lending/program/src/processor.rs index 0db74973d53..ded98c94b96 100644 --- a/token-lending/program/src/processor.rs +++ b/token-lending/program/src/processor.rs @@ -1513,6 +1513,7 @@ fn process_borrow_obligation_liquidity( authority_signer_seeds, token_program: token_program_id.clone(), })?; + } } if owner_fee > 0 { @@ -1524,6 +1525,14 @@ fn process_borrow_obligation_liquidity( authority_signer_seeds, token_program: token_program_id.clone(), })?; + let mut borrow_reserve_temp = Reserve::unpack(&borrow_reserve_info.data.borrow())?; + + if borrow_reserve_liquidity_fee_receiver_info.key == &borrow_reserve_temp.liquidity.supply_pubkey { + borrow_reserve_temp.deposit_liquidity(owner_fee)?; + Reserve::pack(borrow_reserve_temp, &mut borrow_reserve_info.data.borrow_mut())? + } +; + } spl_token_transfer(TokenTransferParams { @@ -2496,6 +2505,12 @@ fn _flash_repay_reserve_liquidity<'a>( authority_signer_seeds: &[], token_program: token_program_id.clone(), })?; + let mut reserve_temp = Reserve::unpack(&reserve_info.data.borrow())?; + + if reserve_liquidity_fee_receiver_info.key == &reserve_temp.liquidity.supply_pubkey { + reserve_temp.deposit_liquidity(origination_fee)?; + Reserve::pack(reserve_temp, &mut reserve_info.data.borrow_mut())?; + } } Ok(()) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000000..fb57ccd13af --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + From d102bac7cbfb92d2f9ca16707df4894f5a26db15 Mon Sep 17 00:00:00 2001 From: Jarett Dunn Date: Thu, 27 Oct 2022 12:31:32 -0300 Subject: [PATCH 2/5] wrong deposit method --- token-lending/program/src/processor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/token-lending/program/src/processor.rs b/token-lending/program/src/processor.rs index ded98c94b96..398abbd5805 100644 --- a/token-lending/program/src/processor.rs +++ b/token-lending/program/src/processor.rs @@ -1528,7 +1528,7 @@ fn process_borrow_obligation_liquidity( let mut borrow_reserve_temp = Reserve::unpack(&borrow_reserve_info.data.borrow())?; if borrow_reserve_liquidity_fee_receiver_info.key == &borrow_reserve_temp.liquidity.supply_pubkey { - borrow_reserve_temp.deposit_liquidity(owner_fee)?; + borrow_reserve_temp.liquidity.deposit(owner_fee)?; Reserve::pack(borrow_reserve_temp, &mut borrow_reserve_info.data.borrow_mut())? } ; @@ -2508,7 +2508,7 @@ fn _flash_repay_reserve_liquidity<'a>( let mut reserve_temp = Reserve::unpack(&reserve_info.data.borrow())?; if reserve_liquidity_fee_receiver_info.key == &reserve_temp.liquidity.supply_pubkey { - reserve_temp.deposit_liquidity(origination_fee)?; + reserve_temp.liquidity.deposit(origination_fee)?; Reserve::pack(reserve_temp, &mut reserve_info.data.borrow_mut())?; } } From da4da313642e7e631d673a07278017a680e61537 Mon Sep 17 00:00:00 2001 From: Jarett Dunn Date: Thu, 27 Oct 2022 12:33:12 -0300 Subject: [PATCH 3/5] cleaned up files --- airdrop.sh | 9 ------ deploy_token_lending.sh | 70 +++++++++++++++++++++++++++++------------ yarn.lock | 4 --- 3 files changed, 50 insertions(+), 33 deletions(-) delete mode 100644 airdrop.sh delete mode 100644 yarn.lock diff --git a/airdrop.sh b/airdrop.sh deleted file mode 100644 index f272dd9ee79..00000000000 --- a/airdrop.sh +++ /dev/null @@ -1,9 +0,0 @@ -while : - -do - -solana airdrop 1 - -sleep 4 - -done diff --git a/deploy_token_lending.sh b/deploy_token_lending.sh index a72f7404454..387fd812fb2 100755 --- a/deploy_token_lending.sh +++ b/deploy_token_lending.sh @@ -6,7 +6,7 @@ PROGRAM_ID=$2; OWNER=`grep 'keypair_path:' $SOLANA_CONFIG | awk '{print $2}'`; MARKET_OWNER=`solana --config $SOLANA_CONFIG address`; -spl-token --config $SOLANA_CONFIG unwrap; +target/debug/spl-token --config $SOLANA_CONFIG unwrap; set -e; echo "Using Solana config filepath: $SOLANA_CONFIG"; @@ -14,16 +14,17 @@ echo "Program ID: $PROGRAM_ID"; echo "Owner: $OWNER"; echo "Market Owner $MARKET_OWNER"; -solana config set --url https://solana-devnet.g.alchemy.com/v2/4Q5FSmnGz3snzIr01s-ZNwAtdFdnDB9L; +solana config set --url https://api.devnet.solana.com; -SOURCE=`spl-token --config $SOLANA_CONFIG wrap 1 2>&1 | head -n1 | awk '{print $NF}'`; +solana airdrop 10 $MARKET_OWNER; +SOURCE=`target/debug/spl-token --config $SOLANA_CONFIG wrap 10 2>&1 | head -n1 | awk '{print $NF}'`; solana program --config $SOLANA_CONFIG deploy \ --program-id $PROGRAM_ID \ target/deploy/solend_program.so; echo "Creating Lending Market"; -CREATE_MARKET_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID create-market \ +CREATE_MARKET_OUTPUT=`target/debug/solend-program create-market \ --fee-payer $OWNER \ --market-owner $MARKET_OWNER \ --verbose`; @@ -32,15 +33,37 @@ echo "$CREATE_MARKET_OUTPUT"; MARKET_ADDR=`echo $CREATE_MARKET_OUTPUT | head -n1 | awk '{print $4}'`; AUTHORITY_ADDR=`echo $CREATE_MARKET_OUTPUT | grep "Authority Address" | awk '{print $NF}'`; +echo "Creating SOL reserve"; +SOL_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ + --fee-payer $OWNER \ + --market-owner $OWNER \ + --source-owner $OWNER \ + --market $MARKET_ADDR \ + --source $SOURCE \ + --amount 5 \ + --pyth-product 3Mnn2fX6rQyUsyELYms1sBJyChWofzSNRoqYzvgMVz5E \ + --pyth-price J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix \ + --switchboard-feed AdtRGGhmqvom3Jemp5YNrxd9q9unX36BZk1pujkkXijL \ + --optimal-utilization-rate 80 \ + --loan-to-value-ratio 75 \ + --liquidation-bonus 5 \ + --liquidation-threshold 80 \ + --min-borrow-rate 0 \ + --optimal-borrow-rate 12 \ + --max-borrow-rate 150 \ + --host-fee-percentage 50 \ + --deposit-limit 40000 \ + --verbose`; +echo "$SOL_RESERVE_OUTPUT"; # USDC Reserve echo "Creating USDC Reserve"; -USDC_TOKEN_MINT=`spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; +USDC_TOKEN_MINT=`target/debug/spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; echo "USDC MINT: $USDC_TOKEN_MINT" -USDC_TOKEN_ACCOUNT=`spl-token --config $SOLANA_CONFIG create-account $USDC_TOKEN_MINT | awk '{print $3}'`; -spl-token --config $SOLANA_CONFIG mint $USDC_TOKEN_MINT 30000000; +USDC_TOKEN_ACCOUNT=`target/debug/spl-token --config $SOLANA_CONFIG create-account $USDC_TOKEN_MINT | awk '{print $3}'`; +target/debug/spl-token --config $SOLANA_CONFIG mint $USDC_TOKEN_MINT 30000000; -USDC_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-reserve \ +USDC_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ --fee-payer $OWNER \ --market-owner $OWNER \ --source-owner $OWNER \ @@ -58,18 +81,18 @@ USDC_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-re --optimal-borrow-rate 8 \ --max-borrow-rate 50 \ --host-fee-percentage 50 \ - --deposit-limit 1000000 --protocol-take-rate 1 --protocol-liquidation-fee 1 \ + --deposit-limit 1000000 \ --verbose`; echo "$USDC_RESERVE_OUTPUT"; # ETH Reserve echo "Creating ETH Reserve" -ETH_TOKEN_MINT=`spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; +ETH_TOKEN_MINT=`target/debug/spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; echo "ETH MINT: $ETH_TOKEN_MINT" -ETH_TOKEN_ACCOUNT=`spl-token --config $SOLANA_CONFIG create-account $ETH_TOKEN_MINT | awk '{print $3}'`; -spl-token --config $SOLANA_CONFIG mint $ETH_TOKEN_MINT 8000000; +ETH_TOKEN_ACCOUNT=`target/debug/spl-token --config $SOLANA_CONFIG create-account $ETH_TOKEN_MINT | awk '{print $3}'`; +target/debug/spl-token --config $SOLANA_CONFIG mint $ETH_TOKEN_MINT 8000000; -ETH_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-reserve \ +ETH_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ --fee-payer $OWNER \ --market-owner $OWNER \ --source-owner $OWNER \ @@ -87,18 +110,18 @@ ETH_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-res --optimal-borrow-rate 8 \ --max-borrow-rate 100 \ --host-fee-percentage 50 \ - --deposit-limit 500 --protocol-take-rate 1 --protocol-liquidation-fee 1 \ + --deposit-limit 500 \ --verbose`; echo "$ETH_RESERVE_OUTPUT"; echo "Creating BTC Reserve" -BTC_TOKEN_MINT=`spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; +BTC_TOKEN_MINT=`target/debug/spl-token --config $SOLANA_CONFIG create-token --decimals 6 | awk '{print $3}'`; echo "BTC MINT: $BTC_TOKEN_MINT" -BTC_TOKEN_ACCOUNT=`spl-token --config $SOLANA_CONFIG create-account $BTC_TOKEN_MINT | awk '{print $3}'`; -spl-token --config $SOLANA_CONFIG mint $BTC_TOKEN_MINT 8000000; +BTC_TOKEN_ACCOUNT=`target/debug/spl-token --config $SOLANA_CONFIG create-account $BTC_TOKEN_MINT | awk '{print $3}'`; +target/debug/spl-token --config $SOLANA_CONFIG mint $BTC_TOKEN_MINT 8000000; -BTC_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-reserve \ +BTC_RESERVE_OUTPUT=`target/debug/solend-program add-reserve \ --fee-payer $OWNER \ --market-owner $OWNER \ --source-owner $OWNER \ @@ -116,11 +139,11 @@ BTC_RESERVE_OUTPUT=` target/debug/solend-program --program $PROGRAM_ID add-res --optimal-borrow-rate 8 \ --max-borrow-rate 100 \ --host-fee-percentage 50 \ - --deposit-limit 30 --protocol-take-rate 1 --protocol-liquidation-fee 1 \ + --deposit-limit 30 \ --verbose`; echo "$BTC_RESERVE_OUTPUT"; -spl-token --config $SOLANA_CONFIG unwrap; +target/debug/spl-token --config $SOLANA_CONFIG unwrap; # Export variables for new config.ts file CONFIG_TEMPLATE_FILE="https://raw.githubusercontent.com/solendprotocol/common/master/src/devnet_template.json" @@ -133,6 +156,13 @@ export BTC_MINT_ADDRESS="$BTC_TOKEN_MINT"; export MAIN_MARKET_ADDRESS="$MARKET_ADDR"; export MAIN_MARKET_AUTHORITY_ADDRESS="$AUTHORITY_ADDR"; +# Reserves +export SOL_RESERVE_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding reserve" | awk '{print $NF}'`; +export SOL_RESERVE_COLLATERAL_MINT_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding collateral mint" | awk '{print $NF}'`; +export SOL_RESERVE_COLLATERAL_SUPPLY_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding collateral supply" | awk '{print $NF}'`; +export SOL_RESERVE_LIQUIDITY_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding liquidity supply" | awk '{print $NF}'`; +export SOL_RESERVE_LIQUIDITY_FEE_RECEIVER_ADDRESS=`echo "$SOL_RESERVE_OUTPUT" | grep "Adding liquidity fee receiver" | awk '{print $NF}'`; + export USDC_RESERVE_ADDRESS=`echo "$USDC_RESERVE_OUTPUT" | grep "Adding reserve" | awk '{print $NF}'`; export USDC_RESERVE_COLLATERAL_MINT_ADDRESS=`echo "$USDC_RESERVE_OUTPUT" | grep "Adding collateral mint" | awk '{print $NF}'`; export USDC_RESERVE_COLLATERAL_SUPPLY_ADDRESS=`echo "$USDC_RESERVE_OUTPUT" | grep "Adding collateral supply" | awk '{print $NF}'`; diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index fb57ccd13af..00000000000 --- a/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - From 103601a2df2ac64ecdd9151820d453f963831040 Mon Sep 17 00:00:00 2001 From: Jarett Dunn Date: Thu, 27 Oct 2022 12:56:47 -0300 Subject: [PATCH 4/5] checks n balances --- token-lending/program/src/processor.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/token-lending/program/src/processor.rs b/token-lending/program/src/processor.rs index 398abbd5805..a29443c06a0 100644 --- a/token-lending/program/src/processor.rs +++ b/token-lending/program/src/processor.rs @@ -1528,10 +1528,21 @@ fn process_borrow_obligation_liquidity( let mut borrow_reserve_temp = Reserve::unpack(&borrow_reserve_info.data.borrow())?; if borrow_reserve_liquidity_fee_receiver_info.key == &borrow_reserve_temp.liquidity.supply_pubkey { + + if Decimal::from(owner_fee) + .try_add(borrow_reserve_temp.liquidity.total_supply()?)? + .try_floor_u64()? + > borrow_reserve_temp.config.deposit_limit + { + msg!("Cannot deposit liquidity above the reserve deposit limit"); + return Err(LendingError::InvalidAmount.into()); + } borrow_reserve_temp.liquidity.deposit(owner_fee)?; + + borrow_reserve_temp.last_update.mark_stale(); + Reserve::pack(borrow_reserve_temp, &mut borrow_reserve_info.data.borrow_mut())? } -; } @@ -2508,7 +2519,18 @@ fn _flash_repay_reserve_liquidity<'a>( let mut reserve_temp = Reserve::unpack(&reserve_info.data.borrow())?; if reserve_liquidity_fee_receiver_info.key == &reserve_temp.liquidity.supply_pubkey { + if Decimal::from(origination_fee) + .try_add(reserve_temp.liquidity.total_supply()?)? + .try_floor_u64()? + > reserve_temp.config.deposit_limit + { + msg!("Cannot deposit liquidity above the reserve deposit limit"); + return Err(LendingError::InvalidAmount.into()); + } reserve_temp.liquidity.deposit(origination_fee)?; + + reserve_temp.last_update.mark_stale(); + Reserve::pack(reserve_temp, &mut reserve_info.data.borrow_mut())?; } } From 32ac96005c85fb82cffe87c94339252cab0b2ce0 Mon Sep 17 00:00:00 2001 From: Jarett Dunn Date: Wed, 2 Nov 2022 00:21:44 -0300 Subject: [PATCH 5/5] testing flash loan and depositor incentives --- .../program/tests/flash_borrow_repay.rs | 255 +++++++++++++++++- 1 file changed, 253 insertions(+), 2 deletions(-) diff --git a/token-lending/program/tests/flash_borrow_repay.rs b/token-lending/program/tests/flash_borrow_repay.rs index b32f138880e..7d5c42f7ec0 100644 --- a/token-lending/program/tests/flash_borrow_repay.rs +++ b/token-lending/program/tests/flash_borrow_repay.rs @@ -17,9 +17,11 @@ use solana_sdk::{ use solend_program::{ error::LendingError, instruction::{ - flash_borrow_reserve_liquidity, flash_repay_reserve_liquidity, LendingInstruction, + flash_borrow_reserve_liquidity, flash_repay_reserve_liquidity, redeem_reserve_collateral, + refresh_reserve, update_reserve_config, LendingInstruction, }, processor::process_instruction, + state::{ReserveConfig, ReserveFees}, }; use spl_token::error::TokenError; use spl_token::instruction::approve; @@ -45,7 +47,7 @@ async fn test_success() { let mut reserve_config = test_reserve_config(); reserve_config.fees.host_fee_percentage = 20; reserve_config.fees.flash_loan_fee_wad = 3_000_000_000_000_000; - + reserve_config.deposit_limit = 3_000_000_000_000_000; let usdc_mint = add_usdc_mint(&mut test); let usdc_oracle = add_usdc_oracle(&mut test); let usdc_test_reserve = add_reserve( @@ -1306,6 +1308,255 @@ async fn test_fail_repay_from_diff_reserve() { TransactionError::InstructionError(1, PrivilegeEscalation) ); } +#[tokio::test] +async fn test_liquidity_supply_matches_fee_recipient() { + let mut test = ProgramTest::new( + "solend_program", + solend_program::id(), + processor!(process_instruction), + ); + + // limit to track compute unit increase + test.set_compute_max_units(60_000); + + const FLASH_LOAN_AMOUNT: u64 = FRACTIONAL_TO_USDC; + const USER_LIQ_AMOUNT: u64 = FLASH_LOAN_AMOUNT; + const FEE_AMOUNT: u64 = 4500; + const HOST_FEE_AMOUNT: u64 = 1000; + + const COLLATERAL_AMOUNT: u64 = USER_LIQ_AMOUNT / 2; + + let user_accounts_owner = Keypair::new(); + let lending_market = add_lending_market(&mut test); + + let mut reserve_config = test_reserve_config(); + reserve_config.fees.host_fee_percentage = 20; + reserve_config.fees.flash_loan_fee_wad = 5_000_000_000_000_000; + reserve_config.deposit_limit = 3_000_000_000_000_000; + let usdc_mint = add_usdc_mint(&mut test); + let usdc_oracle = add_usdc_oracle(&mut test); + let usdc_test_reserve = add_reserve( + &mut test, + &lending_market, + &usdc_oracle, + &user_accounts_owner, + AddReserveArgs { + user_liquidity_amount: USER_LIQ_AMOUNT, + liquidity_amount: FLASH_LOAN_AMOUNT, + liquidity_mint_pubkey: usdc_mint.pubkey, + liquidity_mint_decimals: usdc_mint.decimals, + config: reserve_config, + ..AddReserveArgs::default() + }, + ); + let mut new_config = usdc_test_reserve.config; + new_config.fee_receiver = usdc_test_reserve.liquidity_supply_pubkey; + let (mut banks_client, payer, recent_blockhash) = test.start().await; + + let before_ctoken_amount = + get_token_balance(&mut banks_client, usdc_test_reserve.user_collateral_pubkey).await; + assert_eq!(before_ctoken_amount, 1000000); + + + lending_market + .deposit( + &mut banks_client, + &user_accounts_owner, + &payer, + &usdc_test_reserve, + COLLATERAL_AMOUNT, + ) + .await; + let mut usdc_reserve = usdc_test_reserve.get_state(&mut banks_client).await; + assert!(usdc_reserve.last_update.stale); + + let initial_ctoken_count = + get_token_balance(&mut banks_client, usdc_test_reserve.user_collateral_pubkey).await; + assert_eq!(initial_ctoken_count, 1000000 + COLLATERAL_AMOUNT); + + let before_balance = + get_token_balance(&mut banks_client, usdc_test_reserve.user_liquidity_pubkey).await; + assert_eq!(before_balance, USER_LIQ_AMOUNT - COLLATERAL_AMOUNT); + //\assert!(usdc_reserve.liquidity.cumulative_borrow_rate_wads > old_borrow_rate); + + let mut transaction = Transaction::new_with_payer( + &[update_reserve_config( + solend_program::id(), + new_config, + usdc_test_reserve.pubkey, + lending_market.pubkey, + lending_market.owner.pubkey(), + usdc_oracle.pyth_product_pubkey, + usdc_oracle.pyth_price_pubkey, + usdc_oracle.switchboard_feed_pubkey, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &lending_market.owner], recent_blockhash); + assert!(banks_client.process_transaction(transaction).await.is_ok()); + let updated_reserve = usdc_test_reserve.get_state(&mut banks_client).await; + assert_eq!(updated_reserve.config, new_config); + + lending_market + .deposit( + &mut banks_client, + &user_accounts_owner, + &payer, + &usdc_test_reserve, + COLLATERAL_AMOUNT / 10, + ) + .await; + + let user_transfer_authority = Keypair::new(); + let mut transaction = Transaction::new_with_payer( + &[ + approve( + &spl_token::id(), + &usdc_test_reserve.user_collateral_pubkey, + &user_transfer_authority.pubkey(), + &user_accounts_owner.pubkey(), + &[], + COLLATERAL_AMOUNT, + ) + .unwrap(), + redeem_reserve_collateral( + solend_program::id(), + COLLATERAL_AMOUNT / 10, + usdc_test_reserve.user_collateral_pubkey, + usdc_test_reserve.user_liquidity_pubkey, + usdc_test_reserve.pubkey, + usdc_test_reserve.collateral_mint_pubkey, + usdc_test_reserve.liquidity_supply_pubkey, + lending_market.pubkey, + user_transfer_authority.pubkey(), + ), + refresh_reserve( + solend_program::id(), + usdc_test_reserve.pubkey, + usdc_oracle.pyth_price_pubkey, + usdc_oracle.switchboard_feed_pubkey, + ), + ], + Some(&payer.pubkey()), + ); + + transaction.sign( + &[&payer, &user_accounts_owner, &user_transfer_authority], + recent_blockhash, + ); + assert!(banks_client.process_transaction(transaction).await.is_ok()); + + let test_redeem_balance = + get_token_balance(&mut banks_client, usdc_test_reserve.user_liquidity_pubkey).await; + assert_eq!(test_redeem_balance - before_balance, 0); + let mut transaction = Transaction::new_with_payer( + &[ + flash_borrow_reserve_liquidity( + solend_program::id(), + FLASH_LOAN_AMOUNT, + usdc_test_reserve.liquidity_supply_pubkey, + usdc_test_reserve.user_liquidity_pubkey, + usdc_test_reserve.pubkey, + lending_market.pubkey, + ), + flash_repay_reserve_liquidity( + solend_program::id(), + FLASH_LOAN_AMOUNT, + 0, + usdc_test_reserve.user_liquidity_pubkey, + usdc_test_reserve.liquidity_supply_pubkey, + usdc_test_reserve.liquidity_supply_pubkey, + usdc_test_reserve.liquidity_host_pubkey, + usdc_test_reserve.pubkey, + lending_market.pubkey, + user_accounts_owner.pubkey(), + ), + refresh_reserve( + solend_program::id(), + usdc_test_reserve.pubkey, + usdc_oracle.pyth_price_pubkey, + usdc_oracle.switchboard_feed_pubkey, + ), + ], + Some(&payer.pubkey()), + ); + + transaction.sign(&[&payer, &user_accounts_owner], recent_blockhash); + assert!(banks_client.process_transaction(transaction).await.is_ok()); + + let fee_balance = + get_token_balance(&mut banks_client, usdc_test_reserve.config.fee_receiver).await; + assert_eq!(fee_balance, 0); + + let host_fee_balance = + get_token_balance(&mut banks_client, usdc_test_reserve.liquidity_host_pubkey).await; + assert_eq!(host_fee_balance, HOST_FEE_AMOUNT); + + let after_repay_balance = + get_token_balance(&mut banks_client, usdc_test_reserve.user_liquidity_pubkey).await; + assert_eq!( + after_repay_balance, + COLLATERAL_AMOUNT - reserve_config.fees.flash_loan_fee_wad / 1_000_000_000_000 + ); + + let user_transfer_authority = Keypair::new(); + let mut transaction = Transaction::new_with_payer( + &[ + approve( + &spl_token::id(), + &usdc_test_reserve.user_collateral_pubkey, + &user_transfer_authority.pubkey(), + &user_accounts_owner.pubkey(), + &[], + COLLATERAL_AMOUNT, + ) + .unwrap(), + redeem_reserve_collateral( + solend_program::id(), + COLLATERAL_AMOUNT, + usdc_test_reserve.user_collateral_pubkey, + usdc_test_reserve.user_liquidity_pubkey, + usdc_test_reserve.pubkey, + usdc_test_reserve.collateral_mint_pubkey, + usdc_test_reserve.liquidity_supply_pubkey, + lending_market.pubkey, + user_transfer_authority.pubkey(), + ), + refresh_reserve( + solend_program::id(), + usdc_test_reserve.pubkey, + usdc_oracle.pyth_price_pubkey, + usdc_oracle.switchboard_feed_pubkey, + ), + ], + Some(&payer.pubkey()), + ); + + transaction.sign( + &[&payer, &user_accounts_owner, &user_transfer_authority], + recent_blockhash, + ); + assert!(banks_client.process_transaction(transaction).await.is_ok()); + + let final_ctoken_count = + get_token_balance(&mut banks_client, usdc_test_reserve.user_collateral_pubkey).await; + assert_eq!(final_ctoken_count, 1000000); + + let final_bal = + get_token_balance(&mut banks_client, usdc_test_reserve.user_liquidity_pubkey).await; + assert!( + final_bal > COLLATERAL_AMOUNT - reserve_config.fees.flash_loan_fee_wad / 1_000_000_000_000 + ); + let usdc_reserve = usdc_test_reserve.get_state(&mut banks_client).await; + + let liquidity_supply = + get_token_balance(&mut banks_client, usdc_test_reserve.liquidity_supply_pubkey).await; + assert!(liquidity_supply < FLASH_LOAN_AMOUNT + FEE_AMOUNT - HOST_FEE_AMOUNT); + + assert!( + usdc_reserve.liquidity.available_amount < FLASH_LOAN_AMOUNT + FEE_AMOUNT - HOST_FEE_AMOUNT + ); +} // don't explicitly check user_transfer_authority signer #[allow(clippy::too_many_arguments)]