Skip to content

Commit

Permalink
feat: update price of deposited assets on lend page
Browse files Browse the repository at this point in the history
  • Loading branch information
Teolhyn committed Sep 10, 2024
1 parent 78f8cdf commit 3039336
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 15 deletions.
13 changes: 12 additions & 1 deletion contracts/loan_manager/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod loan_pool {

// This is the real address of the Reflector Oracle in testnet.
// We use the same adress to mock it for testing.
const REFLECTOR_ADDRESS: &str = "CBKZFI26PDCZUJ5HYYKVB5BWCNYUSNA5LVL4R2JTRVSOB4XEP7Y34OPN";
const REFLECTOR_ADDRESS: &str = "CCYOZJCOPG34LLQQ7N24YXBM7LL62R7ONMZ3G6WZAAYPB5OYKOMJRN63";

#[allow(dead_code)]
pub trait LoansTrait {
Expand All @@ -36,6 +36,7 @@ pub trait LoansTrait {
token_collateral_amount: i128,
) -> i128;
fn get_loan(e: &Env, addr: Address) -> Loan;
fn get_price(e: &Env, token: Symbol) -> i128;
}

#[allow(dead_code)]
Expand Down Expand Up @@ -210,6 +211,16 @@ impl LoansTrait for LoansContract {
panic!() // TODO: It should be panic_with_error or something and give out detailed error.
}
}

fn get_price(e: &Env, token: Symbol) -> i128 {
let reflector_address = Address::from_string(&String::from_str(e, REFLECTOR_ADDRESS));
let reflector_contract = oracle::Client::new(e, &reflector_address);

let asset = Asset::Other(token);

let asset_pricedata = reflector_contract.lastprice(&asset).unwrap();
asset_pricedata.price
}
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion contracts/loan_pool/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ contractmeta!(
);

// TODO: get this dynamically when creating the contract.
const LOAN_MANAGER_ADDRESS: &str = "CDIK5MXMF5F3TRW7XHPMUXGHDKBH2SESVDSG2RFGOP2GHXOPCDHTC7VO";
const LOAN_MANAGER_ADDRESS: &str = "CBCAJ6EHX4NEDXLLIZEVOTNMXOBMOGJMMX6X7ARVNTUGJX5DTXAGZM3R";

#[allow(dead_code)]
pub trait LoanPoolTrait {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/_borrow/BorrowableAssetCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { Currency } from 'src/currencies';
import { useWallet } from 'src/stellar-wallet';

// Temporary hack to use XLM pool for all loans and collaterals.
const XLM_LOAN_POOL_ID = 'CCME5C2PJFCWGW5O5MCO4O6X3AUJLD6XHVH3ZJHC7SD7XK5OTPJRPHF7';
const XLM_LOAN_POOL_ID = 'CCRWVENKGBUX7EP273GOUMY542VWRFEEIHUICTTDDG5ESLSDNENCH6AT';

interface BorrowableAssetCardProps {
currency: Currency;
Expand Down
66 changes: 54 additions & 12 deletions src/pages/_lend/LendableAssetCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Button } from '@components/Button';
import { Card } from '@components/Card';
import loanManager from '@contracts/loan_manager';
import { useCallback, useEffect, useState } from 'react';
import type { Currency } from 'src/currencies';
import { useWallet } from 'src/stellar-wallet';
Expand All @@ -12,11 +13,11 @@ export const LendableAssetCard = ({ currency }: LendableAssetCardProps) => {
const { icon, name, symbol, loanPoolContract } = currency;
const { wallet, signTransaction } = useWallet();

const [totalSupplied, setTotalSupplied] = useState<string>('0');
const [supplyAPY, setSupplyAPY] = useState<string>('0.00%');
const [totalSupplied, setTotalSupplied] = useState<bigint | null>(null);
const [totalSuppliedPrice, setTotalSuppliedPrice] = useState<bigint | null>(null);
const [supplyAPY, setSupplyAPY] = useState('0.00%');

// Memoize fetchContractData so it doesn't get recreated on every render
const fetchContractData = useCallback(async () => {
const fetchAvailableContractBalance = useCallback(async () => {
if (!loanPoolContract) return;

try {
Expand All @@ -25,15 +26,18 @@ export const LendableAssetCard = ({ currency }: LendableAssetCardProps) => {
const supplied_lo = BigInt(supplied.simulation.result.retval._value._attributes.lo);
const supplied_combined = (supplied_hi << BigInt(64)) + supplied_lo;

setTotalSupplied(formatSuppliedAmount(supplied_combined));
setTotalSupplied(supplied_combined);
// const apy = await loanPoolContract.getSupplyAPY();
// setSupplyAPY(formatAPY(apy));
} catch (error) {
console.error('Error fetching contract data:', error);
}
}, [loanPoolContract]); // Dependency on loanPoolContract

const formatSuppliedAmount = useCallback((amount: bigint) => {
const formatSuppliedAmount = useCallback((amount: bigint | null) => {
if (amount === BigInt(0)) return '0';
if (!amount) return 'Loading';

const ten_k = BigInt(10_000 * 10_000_000);
const one_m = BigInt(1_000_000 * 10_000_000);
switch (true) {
Expand All @@ -46,14 +50,52 @@ export const LendableAssetCard = ({ currency }: LendableAssetCardProps) => {
}
}, []);

const fetchPriceData = useCallback(async () => {
if (!loanManager) return;

try {
const currentPrice = await loanManager.get_price({ token: currency.symbol });
const price_hi = BigInt(currentPrice.simulation.result.retval._value._attributes.hi);
const price_lo = BigInt(currentPrice.simulation.result.retval._value._attributes.lo);
const price_combined = (price_hi << BigInt(64)) + price_lo;
console.log(price_combined);

setTotalSuppliedPrice(price_combined);
} catch (error) {
console.error('Error fetchin price data:', error);
}
}, [currency.symbol]);

const formatSuppliedAmountPrice = useCallback(
(price: bigint | null) => {
if (totalSupplied === BigInt(0)) return '$0';
if (!totalSupplied || !price) return 'Loading';

const ten_k = BigInt(10_000 * 10_000_000);
const one_m = BigInt(1_000_000 * 10_000_000);
const total_price = ((price / BigInt(10_000_000)) * totalSupplied) / BigInt(10_000_000);
console.log(total_price);
switch (true) {
case total_price > one_m:
return `$${(Number(total_price) / (1_000_000 * 10_000_000)).toFixed(2)}M`;
case total_price > ten_k:
return `$${(Number(total_price) / (1_000 * 10_000_000)).toFixed(1)}K`;
default:
return `$${(Number(total_price) / 10_000_000).toFixed(1)}`;
}
},
[totalSupplied],
);

useEffect(() => {
// Fetch contract data immediately and set an interval to run every 6 seconds
fetchContractData();
const intervalId = setInterval(fetchContractData, 6000);
fetchAvailableContractBalance();
fetchPriceData();
const intervalId = setInterval(fetchAvailableContractBalance, 6000);

// Cleanup function to clear the interval on component unmount
return () => clearInterval(intervalId);
}, [fetchContractData]); // Now dependent on the memoized function
}, [fetchAvailableContractBalance, fetchPriceData]); // Now dependent on the memoized function

const handleDepositClick = async () => {
if (!wallet) {
Expand All @@ -72,7 +114,7 @@ export const LendableAssetCard = ({ currency }: LendableAssetCardProps) => {
} catch (err) {
alert(`Error depositing: ${JSON.stringify(err)}`);
}
fetchContractData();
fetchAvailableContractBalance();
};

return (
Expand All @@ -86,8 +128,8 @@ export const LendableAssetCard = ({ currency }: LendableAssetCardProps) => {

<div className="w-64">
<p className="text-grey">Total Supplied</p>
<p className="text-xl font-bold leading-6">{totalSupplied}</p>
<p>$5.82M</p>
<p className="text-xl font-bold leading-6">{formatSuppliedAmount(totalSupplied)}</p>
<p>{formatSuppliedAmountPrice(totalSuppliedPrice)}</p>
</div>

<div className="w-64">
Expand Down

0 comments on commit 3039336

Please sign in to comment.