Get different result of sumulate same contract function in rust-sdk and ts-sdk

Hello guys

Having trouble with getting a result from the smart contract function in Typescript SDK, it returns me ‘0’, but Rust SDK returns a correct value that is more than 0.

Here is Rust code:

use std::str::FromStr;

use crate::utils::contracts_utils::market_utils::{market_abi_calls, MarketContract};
use crate::utils::contracts_utils::oracle_utils::{oracle_abi_calls, OracleContract};
use crate::utils::print_title;
use fuels::accounts::wallet::WalletUnlocked;
use fuels::accounts::ViewOnlyAccount;
use fuels::prelude::Provider;
use fuels::types::{Address, ContractId};

// Multiplies all values by this number
// It is necessary in order to test how the protocol works with large amounts
const RPC: &str = "beta-4.fuel.network";
const ORACLE_ADDRESS: &str = "0x633fad7666495c53daa41cc329b78a554f215af4b826671ee576f2a30096999d";
const MARKET_ADDRESS: &str = "0x2679d41c2981bcd6ab69d66f0ae656077efecac2c2dd729f88f5a6457ce1d5f1";

#[tokio::test]
async fn availtable_to_borrow_test() {
    dotenv::dotenv().ok();

    print_title("Available to borrow");
    //--------------- WALLETS ---------------
    let provider = Provider::connect(RPC).await.unwrap();

    let admin_pk = std::env::var("ADMIN").unwrap().parse().unwrap();
    let admin = WalletUnlocked::new_from_private_key(admin_pk, Some(provider.clone()));

    let alice_pk = std::env::var("ALICE").unwrap().parse().unwrap();
    let alice = WalletUnlocked::new_from_private_key(alice_pk, Some(provider.clone()));
    let alice_address = Address::from(alice.address());

    println!("Alice address = {:?}", alice.address().to_string());
    //--------------- ORACLE ---------------
    let id = ContractId::from_str(ORACLE_ADDRESS).unwrap();
    let oracle = OracleContract::new(id, admin.clone());
    let contracts = oracle_abi_calls::get_as_settable_contract(&oracle);

    //--------------- MARKET ---------------
    let id = ContractId::from_str(MARKET_ADDRESS).unwrap();
    let market = MarketContract::new(id, admin.clone());

    let value = market_abi_calls::available_to_borrow(&market, &contracts, alice_address).await;
    println!("Available to borrow = {}", value);
}

Rust SDK output

Alice address = "fuel1r9xy6hfjr63mct58zz054pjjpttqlyjfnrm8qp75slfuczkvghfqs6ndle"
Available to borrow = 396995628

And at the same type I call same func with Typescript SDK

 updateMaxBorrowAmount = async (marketContract: MarketAbi) => {
    const { addressInput, address } = this.rootStore.accountStore;
    if (addressInput == null) return;
    const { priceOracle } = this.rootStore.settingsStore.currentVersionConfig;
    const oracle = new Contract(
      priceOracle,
      OracleAbi__factory.abi,
      this.rootStore.accountStore.provider
    );
    const { value } = await marketContract.functions
      .available_to_borrow(addressInput)
      .callParams({ gasLimit: 10000 })
      .addContracts([oracle])
      .simulate();  //.dryRun(); works same
    console.log("alice address", addressInput);
    console.log("alice address", address);
    console.log("available_to_borrow", value.toString());
    this.setMaxBorrowBaseTokenAmount(new BN(value.toString()));
  };

Typescript SDK output

alice address {value: '0x194c4d5d321ea3bc2e87109f4a86520ad60f924998f67007d487d3cc0acc45d2'}
fuel1r9xy6hfjr63mct58zz054pjjpttqlyjfnrm8qp75slfuczkvghfqs6ndle
available_to_borrow 0

I assume that the problem is in providing Oracle contact, but don’t know how to do it other way

Hi there! :palm_tree:
Can you share the sway code as well?

It feels like available_to_borrow 0 might be coming from “unwrap_or_(0)”

I don’t think that this could have any impact because… I call the same contract, deployed to testnet beta4, and the same function of this contract, with the same parameters from the same account with rast sdk and ts sdk, but the result is different

Hi @sway, would you be able to share the contract ID and the ABI and I can connect and take a look?

sure

Oracle Abi - https://github.com/compolabs/sway-lend/blob/beta-4/frontend/src/contracts/OracleAbi.d.ts

Market Abi - https://github.com/compolabs/sway-lend/blob/beta-4/frontend/src/contracts/MarketAbi.d.ts

and here are the addresses that are also in rust code sample

const RPC: &str = "beta-4.fuel.network";
const ORACLE_ADDRESS: &str = "0x633fad7666495c53daa41cc329b78a554f215af4b826671ee576f2a30096999d";
const MARKET_ADDRESS: &str = "0x2679d41c2981bcd6ab69d66f0ae656077efecac2c2dd729f88f5a6457ce1d5f1";

And just in case here is link to function - https://github.com/compolabs/sway-lend/blob/8157cdbe979c160dd20e492ab0d10fa0dc482ef0/frontend/src/screens/Dashboard/DashboardVm.tsx#L255

Hey @sway, so there is no issue with how you have gone about providing the contract. The issue is that whereas in the Rust code you are using the admin wallet to instantiate the contracts, and Alice’s wallet to check the borrow amount, and therefore performing a comparison. In the TS code you are only using a single address to instantiate the contracts and to perform the comparrison; being what ever address stored at this.rootStore.accountStore. Hence why the result would be 0 when comparing against the same address.

I was able to retrieve 396995628 using your addresses/contracts using the following test case:

it('can retrieve borrow amount for a given address', async () => {
  const provider = new Provider(`https://beta-4.fuel.network/graphql`);

  const adminAddress = Address.fromString(
    'fuel159djw3jmne4x9kwpxt8y9kenf8272crnxyyx3sn6gej02n4mp48sjufxjw'
  );
  const adminWallet = Wallet.fromAddress(adminAddress, provider);

  const aliceAddress = Address.fromString(
    'fuel1r9xy6hfjr63mct58zz054pjjpttqlyjfnrm8qp75slfuczkvghfqs6ndle'
  );
  const aliceAddressInput = { value: aliceAddress.toB256() };

  const oracleAddress = '0x633fad7666495c53daa41cc329b78a554f215af4b826671ee576f2a30096999d';
  const oracleContract = new Contract(oracleAddress, oracleAbi, adminWallet);

  const marketAddress = '0x2679d41c2981bcd6ab69d66f0ae656077efecac2c2dd729f88f5a6457ce1d5f1';
  const marketContract = new Contract(marketAddress, marketAbi, adminWallet);

  const { value } = await marketContract.functions
    .available_to_borrow(aliceAddressInput)
    .addContracts([oracleContract])
    .simulate();

  expect(value.toNumber()).toBeGreaterThan(0);
});

Let me know if this doesn’t solve it for you :slight_smile:

1 Like

Thanks a lot for helping!

First of all have to say that contract fn available_to_borrow doesn’t rely on the caller address, only on the address that is given as a parameter, so your suggestion of providing admin wallet instance is incorrect, but i have found that error was because of .callParams({ gasLimit: 10000 }), I removed this line with callParams and started to get the same value. Thanks a lot for your help!

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.