Skip to content

Commit

Permalink
cauldronInfo to viem
Browse files Browse the repository at this point in the history
  • Loading branch information
Onipchenko-Andrey committed Oct 18, 2023
1 parent e7b9a96 commit b82f916
Show file tree
Hide file tree
Showing 15 changed files with 3,476 additions and 4 deletions.
9 changes: 9 additions & 0 deletions src/constants/abi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const FEE_PERCENT_ABI = [
{
inputs: [],
name: "feePercent",
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
stateMutability: "view",
type: "function",
},
];
30 changes: 30 additions & 0 deletions src/helpers/cauldron/check/checkIsUserCollateralLockedViem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import moment from "moment";
import { readContract, type Address } from "@wagmi/core";
import type { CauldronConfig } from "@/utils/cauldronsConfig/configTypes";

export const checkIsUserCollateralLockedViem = async (
config: CauldronConfig,
account: Address,
chainId: number
) => {
try {
const { isSSpell } = config.cauldronSettings;
if (chainId !== 1 || !isSSpell) return false;

const [balance, lockedUntil]: any = await readContract({
address: config.collateralInfo.address,
abi: config.collateralInfo.abi,
functionName: "users",
args: [account],
});

const lockTimestamp = lockedUntil.toString();
const currentTimestamp = moment().unix().toString();

if (lockTimestamp && lockTimestamp > currentTimestamp) return lockTimestamp;
return false;
} catch (error) {
console.log("Check Is User Collateral Locked Error:", error);
return false;
}
};
33 changes: 33 additions & 0 deletions src/helpers/cauldron/emptyState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ONE_ETHER_VIEM } from "@/constants/global";

export const userPositionEmptyState = {
collateralInfo: {
userCollateralShare: 0n,
userCollateralAmount: 0n,
},
borrowInfo: {
userBorrowAmount: 0n,
userBorrowPart: 0n,
},
oracleRate: 0n,
liquidationPrice: "0",
};

export const userTokensInfoEmptyState = {
collateralBalance: 0n,
mimBalance: 0n,
nativeTokenBalance: 0n,
collateralAllowance: 0n,
mimAllowance: 0n,
unwrappedTokenBalance: 0n,
unwrappedTokenAllowance: 0n,
};

export const additionalInfoEmptyState = {
isMasterContractApproved: false,
tokensRate: ONE_ETHER_VIEM,
maxWithdrawAmount: 0n,
whitelistedInfo: { isUserWhitelisted: false },
isCollateralLocked: false,
feePercent: null,
};
111 changes: 111 additions & 0 deletions src/helpers/cauldron/getAdditionalInfoViem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { parseUnits } from "viem";
import type { providers } from "ethers";
import bentoBoxAbi from "@/utils/abi/bentoBox";
import type { Address, PublicClient } from "viem";
import type { AdditionalInfo } from "@/types/cauldron";
import { additionalInfoEmptyState } from "@/helpers/cauldron/emptyState";
import { getFeePercentViem } from "@/helpers/cauldron/getFeePercentViem";
import type { CauldronConfig } from "@/utils/cauldronsConfig/configTypes";
import { getWhiteListedInfoViem } from "@/helpers/cauldron/getWhiteListedInfoViem";
import { checkIsUserCollateralLockedViem } from "@/helpers/cauldron/check/checkIsUserCollateralLockedViem";

export const getAdditionalInfoViem = async (
config: CauldronConfig,
account: Address | undefined,
publicClient: PublicClient,
contractProvider: providers.BaseProvider | providers.JsonRpcSigner
): Promise<AdditionalInfo> => {
const { collateralInfo, contract, cauldronSettings } = config;
const { decimals } = collateralInfo;

if (!account) {
additionalInfoEmptyState.tokensRate = parseUnits("1", decimals);
return additionalInfoEmptyState;
}

const [bentoBoxAddress, masterContractAddress] = await publicClient.multicall(
{
contracts: [
{
address: contract.address,
abi: contract.abi,
functionName: "bentoBox",
args: [],
},
{
address: contract.address,
abi: contract.abi,
functionName: "masterContract",
args: [],
},
],
}
);

const contracts: any = [
{
address: bentoBoxAddress.result,
abi: bentoBoxAbi,
functionName: "masterContractApproved",
args: [masterContractAddress.result, account],
},
{
address: collateralInfo.address,
abi: collateralInfo.abi,
functionName: "convertToAssets",
args: [parseUnits("1", collateralInfo.decimals)],
},
{
address: collateralInfo.address,
abi: collateralInfo.abi,
functionName: "toAmount",
args: [parseUnits("1", collateralInfo.decimals)],
},
];

if (cauldronSettings.hasWithdrawableLimit) {
contracts.push({
address: collateralInfo.address,
abi: collateralInfo.abi,
functionName: "balanceOf",
args: [bentoBoxAddress.result],
});
}

const additionalInfo: any = await publicClient.multicall({ contracts });

const tokensRate: any = additionalInfo[1]?.error
? additionalInfo[2]?.error
? parseUnits("1", decimals)
: additionalInfo[2]?.result
: additionalInfo[1]?.result;

const whitelistedInfo = await getWhiteListedInfoViem(
config,
publicClient.chain!.id,
account,
publicClient,
contractProvider
);

const isCollateralLocked = await checkIsUserCollateralLockedViem(
config,
account,
publicClient.chain!.id
);

const feePercent = await getFeePercentViem(
config,
publicClient,
publicClient.chain!.id
);

return {
isMasterContractApproved: additionalInfo[0]?.result || false,
tokensRate,
maxWithdrawAmount: additionalInfo[3]?.result || 0n,
whitelistedInfo,
isCollateralLocked,
feePercent,
};
};
56 changes: 56 additions & 0 deletions src/helpers/cauldron/getCauldronInfoViem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { providers } from "ethers";
import { getAccount } from "@wagmi/core";
import cauldronsConfig from "@/utils/cauldronsConfig";
import type { CauldronInfo } from "@/types/cauldron/index";
import { getPublicClient } from "@/helpers/cauldron/getPublicClient";
import { getMainParamsViem } from "@/helpers/cauldron/getMainParamsViem";
import { getUserPositionsViem } from "@/helpers/cauldron/getUserPositionsViem";
import { getUserTokensInfoViem } from "@/helpers/cauldron/getUserTokensInfoViem";
import { getAdditionalInfoViem } from "@/helpers/cauldron/getAdditionalInfoViem";

export const getCauldronInfoViem = async (
cauldronId: number,
chainId: number,
provider: providers.BaseProvider,
signer: providers.JsonRpcSigner
): Promise<CauldronInfo | null> => {
const { address } = getAccount();
const contractProvider = address ? signer : provider;

const config = cauldronsConfig.find(
(config) => +config.id === +cauldronId && +config.chainId === +chainId
);

if (!config) return null;

const publicClient = getPublicClient(chainId);

const mainParams = await getMainParamsViem([config], publicClient);

const userPositions = await getUserPositionsViem(
[config],
publicClient,
address
);

const userTokensInfo = await getUserTokensInfoViem(
config,
address,
publicClient
);

const additionalInfo = await getAdditionalInfoViem(
config,
address,
publicClient,
contractProvider
);

return {
config,
mainParams: mainParams[0],
userPosition: userPositions[0],
userTokensInfo,
additionalInfo,
};
};
18 changes: 18 additions & 0 deletions src/helpers/cauldron/getFeePercentViem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { PublicClient } from "viem";
import { FEE_PERCENT_ABI } from "@/constants/abi";
import type { CauldronConfig } from "@/utils/cauldronsConfig/configTypes";

export const getFeePercentViem = async (
config: CauldronConfig,
publicClient: PublicClient,
chainId: number
): Promise<bigint | unknown> => {
if (chainId !== 42161 && config.id !== 2) return 0n;

return await publicClient.readContract({
address: config.collateralInfo.address,
abi: FEE_PERCENT_ABI,
functionName: "feePercent",
args: [],
});
};
22 changes: 22 additions & 0 deletions src/helpers/cauldron/getLensContractViem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import lensAbi from "@/utils/abi/marketLens.js";
import type { ContractInfo } from "@/types/global";

export const getLensContractViem = (chainId: number): ContractInfo => {
switch (chainId) {
case 1:
return {
address: "0x26ecfcd82bf36427006794d41927da334f762230",
abi: lensAbi,
};
case 2222:
return {
address: "0x2d50927A6E87E517946591A137b765fAba018E70",
abi: lensAbi,
};
default:
return {
address: "0x73f52bd9e59edbdf5cf0dd59126cef00ecc31528",
abi: lensAbi,
};
}
};
54 changes: 54 additions & 0 deletions src/helpers/cauldron/getMainParamsViem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { formatUnits } from "viem";
import type { PublicClient } from "viem";
import type { MainParams } from "@/types/cauldron";
import type { CauldronConfig } from "@/utils/cauldronsConfig/configTypes";
import { getLensContractViem } from "@/helpers/cauldron/getLensContractViem";

export const getMainParamsViem = async (
configs: CauldronConfig[],
publicClient: PublicClient
): Promise<MainParams[]> => {
const cauldronMarketInfo = await Promise.all(
configs.map(({ version, contract }: CauldronConfig) => {
return publicClient.readContract({
...getLensContractViem(publicClient.chain!.id),
functionName: `getMarketInfoCauldronV${version === 2 ? 2 : 3}`,
args: [contract.address],
});
})
);

return await Promise.all(
cauldronMarketInfo.map(async (marketInfo: any, index: number) => {
const { contract, interest: localInterest } = configs[index];

const contractExchangeRate = await publicClient.readContract({
...contract,
functionName: "exchangeRate",
args: [],
});

const updatePrice = contractExchangeRate
? contractExchangeRate !== marketInfo.oracleExchangeRate
: false;

const interest = localInterest
? localInterest
: +formatUnits(marketInfo.interestPerYear, 0) / 100;

return {
borrowFee: +formatUnits(marketInfo.borrowFee, 0) / 100,
interest,
liquidationFee: +formatUnits(marketInfo.liquidationFee, 2),
collateralPrice: marketInfo.collateralPrice,
mimLeftToBorrow: marketInfo.marketMaxBorrow,
maximumCollateralRatio: marketInfo.maximumCollateralRatio,
oracleExchangeRate: marketInfo.oracleExchangeRate,
totalBorrowed: marketInfo.totalBorrowed,
tvl: marketInfo.totalCollateral.value,
userMaxBorrow: marketInfo.userMaxBorrow,
updatePrice,
};
})
);
};
9 changes: 9 additions & 0 deletions src/helpers/cauldron/getPublicClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { chainsList } from "@/helpers/chains";
import { createPublicClient, http, type PublicClient } from "viem";

export const getPublicClient = (chainId: number): PublicClient => {
return createPublicClient({
chain: chainsList[chainId as keyof typeof chainsList],
transport: http(),
});
};
Loading

0 comments on commit b82f916

Please sign in to comment.