Skip to content

Project 10: Borrow logic compares USD collateral to token amount without converting units #63

@khal45

Description

@khal45

In the lending section of the bootcamp, the collateral is calculated as such

@> let total_collateral: u64;

    match ctx.accounts.mint.to_account_info().key() {
        key if key == user.usdc_address => {
            let sol_feed_id = get_feed_id_from_hex(SOL_USD_FEED_ID)?; 
            let sol_price = price_update.get_price_no_older_than(&Clock::get()?, MAXIMUM_AGE, &sol_feed_id)?;
            let accrued_interest = calculate_accrued_interest(user.deposited_sol, bank.interest_rate, user.last_updated)?;
@>            total_collateral = sol_price.price as u64 * (user.deposited_sol + accrued_interest);
        },
        _ => {
            let usdc_feed_id = get_feed_id_from_hex(USDC_USD_FEED_ID)?;
            let usdc_price = price_update.get_price_no_older_than(&Clock::get()?, MAXIMUM_AGE, &usdc_feed_id)?;
@>            total_collateral = usdc_price.price as u64 * user.deposited_usdc;

        }
    }

This means total_collateral is in USD, not tokens.
Example

  • SOL = $140
  • USDC = $1
  • User deposited 1000 USDC and accrued 10 USDC interest
total_collateral = 1 * (1000 + 10) = 1010 USD

The borrowable amount is then calculated as such

 let borrowable_amount = total_collateral as u64 *  bank.liquidation_threshold;

Using our example from above and assuming SOL has a liquidation threshold of 0.5(50%)

borrowable_amount = 1010 * 0.5 = 505 USD

That means the user can borrow up to 505 USD worth of SOL with their deposited collateral. But then the code is checking that the borrowable amount is less than the amount passed in the instruction

 if borrowable_amount < amount {
        return Err(ErrorCode::OverBorrowableAmount.into());
    }       

This checks that the USD borrowable amount is less than the amount requested to borrow. Going by my example the line checks

505 (USD) < 2 (SOL) → false

The check passes even though the units are incompatible. Since no USD→token conversion happens, the borrow eligibility check is conceptually incorrect (even if SOL and USDC prices make many cases appear “fine” during testing).
After computing borrowable_amount in USD, the protocol should convert it to tokens and check the borrowable amount in tokens against the amount passed in the instruction

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions