@raac/rpc 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/RPCLibrary.ts +358 -0
- package/assets/getAsset.ts +26 -0
- package/assets/getAssets.ts +30 -0
- package/assets/getSupply.ts +23 -0
- package/configs/chains/8453.json +116 -0
- package/configs/chains/chain.d.ts +87 -0
- package/configs/chains/index.ts +13 -0
- package/configs/chains/list.json +3 -0
- package/configs/createConfig.ts +91 -0
- package/configs/index.ts +51 -0
- package/contracts/crvUSDToken/getBalance.ts +23 -0
- package/contracts/crvUSDToken/getTotalSupply.ts +36 -0
- package/contracts/getContract.ts +21 -0
- package/contracts/getContractAddress.ts +61 -0
- package/contracts/housePrices/getLatestPrice.ts +38 -0
- package/contracts/housePrices/setOracle.ts +40 -0
- package/contracts/rcrvUSDToken/getBalance.ts +23 -0
- package/contracts/rcrvUSDToken/getTotalSupply.ts +39 -0
- package/contracts/zeno/createAuction.ts +57 -0
- package/contracts/zeno/createZeno.ts +45 -0
- package/contracts/zeno/getAuctions.ts +38 -0
- package/contracts/zeno/getZenos.ts +38 -0
- package/custom-types.d.ts +20 -0
- package/index.ts +3 -0
- package/methods/approveToken.ts +47 -0
- package/methods/commons/checkAllowance.ts +36 -0
- package/methods/commons/estimateGasPrice.ts +21 -0
- package/methods/debug/mintToken.js +83 -0
- package/methods/getAssetBalance.ts +47 -0
- package/methods/getAssetsBalance.ts +9 -0
- package/minter/get.ts +150 -0
- package/minter/getApy.ts +37 -0
- package/minter/tick.ts +40 -0
- package/nfts/addNewBatch.ts +37 -0
- package/nfts/getCurrentBatchSize.ts +26 -0
- package/nfts/getDepositedNFTs.ts +31 -0
- package/nfts/getHousePrice.ts +30 -0
- package/nfts/getOwnedNFTs.ts +46 -0
- package/nfts/mint.ts +43 -0
- package/nfts/setBaseUri.ts +33 -0
- package/package.json +27 -0
- package/pools/lendingPool/borrowFromLendingPool.ts +39 -0
- package/pools/lendingPool/depositNFTToLendingPool.ts +70 -0
- package/pools/lendingPool/depositToLendingPool.ts +52 -0
- package/pools/lendingPool/getHousePrice.ts +46 -0
- package/pools/lendingPool/getLendingPoolInfo.ts +153 -0
- package/pools/lendingPool/getLendingPoolTotalLiquidity.ts +32 -0
- package/pools/lendingPool/repayToLendingPool.ts +52 -0
- package/pools/lendingPool/withdrawFromLendingPool.ts +68 -0
- package/pools/lendingPool/withdrawNFTFromLendingPool.ts +39 -0
- package/pools/liquidityPool/getLiquidityPoolInfo.ts +90 -0
- package/pools/stabilityPool/calculateRAACRewards.ts +37 -0
- package/pools/stabilityPool/depositToStabilityPool.ts +47 -0
- package/pools/stabilityPool/getStabilityPoolInfo.ts +121 -0
- package/pools/stabilityPool/getStabilityPoolTotalDeposits.ts +27 -0
- package/pools/stabilityPool/withdrawFromStabilityPool.ts +47 -0
- package/sync-contracts.sh +63 -0
- package/tests/test.ts +40 -0
- package/tsconfig.json +113 -0
- package/utils/artifacts.ts +66 -0
- package/utils/chain.ts +94 -0
- package/utils/config.ts +49 -0
- package/utils/contracts.ts +94 -0
- package/wallet/assets/approveAsset.ts +44 -0
- package/wallet/assets/burnAsset.ts +55 -0
- package/wallet/assets/getAllowance.ts +38 -0
- package/wallet/assets/getAsset.ts +33 -0
- package/wallet/assets/getAssets.ts +35 -0
- package/wallet/assets/getBalance.ts +34 -0
- package/wallet/assets/mintAsset.ts +57 -0
- package/wallet/assets/transferAsset.ts +78 -0
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@raac/rpc",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "RPC Library for RAAC ",
|
|
5
|
+
"main": "RPCLibrary.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
+
"sync": "bash sync-contracts.sh"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"RAAC",
|
|
12
|
+
"RPC",
|
|
13
|
+
"blockchain",
|
|
14
|
+
"DeFi"
|
|
15
|
+
],
|
|
16
|
+
"author": "RAAC",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"ethers": "^6.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"eslint": "^8.0.0",
|
|
23
|
+
"ts-node": "^10.9.2",
|
|
24
|
+
"ts-node-dev": "^2.0.0",
|
|
25
|
+
"typescript": "^5.7.3"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ethers, Signer } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../contracts/getContractAddress";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import { ChainId } from "../../configs/chains/index";
|
|
5
|
+
import { LendingPool } from "../../typechain-types";
|
|
6
|
+
|
|
7
|
+
// checked
|
|
8
|
+
async function borrowFromLendingPool(
|
|
9
|
+
chainId: ChainId,
|
|
10
|
+
tokenId: number | string,
|
|
11
|
+
amount: string,
|
|
12
|
+
signer: Signer
|
|
13
|
+
) {
|
|
14
|
+
try {
|
|
15
|
+
const lendingPoolAddress = getContractAddress(chainId, "lendingpool");
|
|
16
|
+
const lendingPoolABI = getABI("lendingpool");
|
|
17
|
+
|
|
18
|
+
const lendingPoolContract = new ethers.Contract(
|
|
19
|
+
lendingPoolAddress,
|
|
20
|
+
lendingPoolABI,
|
|
21
|
+
signer
|
|
22
|
+
) as any as LendingPool;
|
|
23
|
+
|
|
24
|
+
const tx = await lendingPoolContract.borrow(amount);
|
|
25
|
+
const receipt = await tx.wait();
|
|
26
|
+
|
|
27
|
+
console.log(
|
|
28
|
+
`Borrowed ${ethers.formatEther(amount)} against NFT #${tokenId}`
|
|
29
|
+
);
|
|
30
|
+
console.log(`Transaction hash: ${receipt?.hash}`);
|
|
31
|
+
|
|
32
|
+
return receipt;
|
|
33
|
+
} catch (error: any) {
|
|
34
|
+
console.error("Error in borrowFromLendingPool:", error);
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default borrowFromLendingPool;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { ethers, Signer } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../contracts/getContractAddress";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import estimateGasPrice from "../../methods/commons/estimateGasPrice";
|
|
5
|
+
import { ChainId } from "../../configs/chains";
|
|
6
|
+
import { LendingPool } from "../../typechain-types";
|
|
7
|
+
|
|
8
|
+
//checked
|
|
9
|
+
async function depositNFTToLendingPool(
|
|
10
|
+
chainId: ChainId,
|
|
11
|
+
tokenId: number | string,
|
|
12
|
+
signer: Signer
|
|
13
|
+
) {
|
|
14
|
+
if (!signer) {
|
|
15
|
+
throw new Error("Wallet not connected");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const lendingPoolAddress = getContractAddress(chainId, "lendingpool");
|
|
20
|
+
const nftAddress = getContractAddress(chainId, "raacnft");
|
|
21
|
+
const lendingPoolABI = getABI("lendingpool");
|
|
22
|
+
const nftABI = getABI("raacnft");
|
|
23
|
+
|
|
24
|
+
const lendingPoolContract = new ethers.Contract(
|
|
25
|
+
lendingPoolAddress,
|
|
26
|
+
lendingPoolABI,
|
|
27
|
+
signer
|
|
28
|
+
) as any as LendingPool;
|
|
29
|
+
const nftContract = new ethers.Contract(nftAddress, nftABI, signer);
|
|
30
|
+
|
|
31
|
+
const { maxFeePerGas } = await estimateGasPrice(signer);
|
|
32
|
+
|
|
33
|
+
// Check if the signer owns the NFT
|
|
34
|
+
const owner = await nftContract.ownerOf(tokenId);
|
|
35
|
+
if (owner.toLowerCase() !== (await signer.getAddress()).toLowerCase()) {
|
|
36
|
+
throw new Error(`Signer does not own NFT #${tokenId}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Approve the lending pool to transfer the NFT
|
|
40
|
+
const approveTx = await nftContract.approve(lendingPoolAddress, tokenId, {
|
|
41
|
+
maxFeePerGas,
|
|
42
|
+
nonce: await signer.getNonce(),
|
|
43
|
+
});
|
|
44
|
+
await approveTx.wait();
|
|
45
|
+
console.log(`Approved lending pool to transfer NFT #${tokenId}`);
|
|
46
|
+
|
|
47
|
+
console.log(lendingPoolContract);
|
|
48
|
+
// Deposit (stake) the NFT
|
|
49
|
+
const depositTx = await lendingPoolContract.depositNFT(tokenId, {
|
|
50
|
+
maxFeePerGas,
|
|
51
|
+
nonce: await signer.getNonce(),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
console.log(
|
|
55
|
+
`Deposit transaction sent for NFT #${tokenId}:`,
|
|
56
|
+
depositTx.hash
|
|
57
|
+
);
|
|
58
|
+
const receipt = await depositTx.wait();
|
|
59
|
+
console.log(
|
|
60
|
+
`Deposited NFT #${tokenId} to lending pool successfully:`,
|
|
61
|
+
receipt?.hash
|
|
62
|
+
);
|
|
63
|
+
return receipt;
|
|
64
|
+
} catch (error: any) {
|
|
65
|
+
console.error(`NFT Deposit to Lending Pool error:`, error);
|
|
66
|
+
throw new Error(`NFT Deposit to Lending Pool failed: ${error.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default depositNFTToLendingPool;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ethers, Signer } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../utils/contracts";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import estimateGasPrice from "../../methods/commons/estimateGasPrice";
|
|
5
|
+
import { ChainId } from "../../configs/chains";
|
|
6
|
+
import { LendingPool } from "../../typechain-types";
|
|
7
|
+
|
|
8
|
+
// checked
|
|
9
|
+
async function depositToLendingPool(
|
|
10
|
+
chainId: ChainId,
|
|
11
|
+
amount: string,
|
|
12
|
+
signer: Signer
|
|
13
|
+
) {
|
|
14
|
+
if (!signer) {
|
|
15
|
+
throw new Error("Wallet not connected");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const lendingPoolAddress = getContractAddress(chainId, "lendingpool");
|
|
20
|
+
const lendingPoolABI = getABI("lendingpool");
|
|
21
|
+
|
|
22
|
+
const lendingPoolContract = new ethers.Contract(
|
|
23
|
+
lendingPoolAddress,
|
|
24
|
+
lendingPoolABI,
|
|
25
|
+
signer
|
|
26
|
+
) as any as LendingPool;
|
|
27
|
+
|
|
28
|
+
const amountInWei = ethers.parseEther(amount);
|
|
29
|
+
const { maxFeePerGas } = await estimateGasPrice(signer);
|
|
30
|
+
|
|
31
|
+
const depositTx = await lendingPoolContract.deposit(
|
|
32
|
+
amountInWei.toString(),
|
|
33
|
+
{
|
|
34
|
+
maxFeePerGas,
|
|
35
|
+
nonce: await signer.getNonce(),
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
console.log(`Deposit transaction sent for rcrvusd:`, depositTx.hash);
|
|
40
|
+
const receipt = await depositTx.wait();
|
|
41
|
+
console.log(
|
|
42
|
+
`Deposited ${amount} rcrvusd to lending pool successfully:`,
|
|
43
|
+
receipt?.hash
|
|
44
|
+
);
|
|
45
|
+
return receipt;
|
|
46
|
+
} catch (error: any) {
|
|
47
|
+
console.error(`Lending Pool Deposit error:`, error);
|
|
48
|
+
throw new Error(`Lending Pool Deposit failed: ${error.message}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default depositToLendingPool;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ethers, Signer } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../contracts/getContractAddress";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import { ChainId } from "../../configs/chains/index";
|
|
5
|
+
import { RAACHousePrices } from "../../typechain-types";
|
|
6
|
+
|
|
7
|
+
// checked
|
|
8
|
+
async function getHousePrice(
|
|
9
|
+
chainId: ChainId,
|
|
10
|
+
tokenId: number | string,
|
|
11
|
+
signer: Signer
|
|
12
|
+
) {
|
|
13
|
+
console.log(chainId, tokenId, signer);
|
|
14
|
+
if (!signer) {
|
|
15
|
+
throw new Error("Wallet not connected");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const raacHousePricesAddress = getContractAddress(
|
|
20
|
+
chainId,
|
|
21
|
+
"raachouseprices"
|
|
22
|
+
) as any as RAACHousePrices;
|
|
23
|
+
const raacHousePricesABI = getABI("raachouseprices");
|
|
24
|
+
|
|
25
|
+
const raacHousePricesContract = new ethers.Contract(
|
|
26
|
+
raacHousePricesAddress,
|
|
27
|
+
raacHousePricesABI,
|
|
28
|
+
signer
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const housePrice = await raacHousePricesContract.getLatestPrice(tokenId);
|
|
32
|
+
console.log({ housePrice });
|
|
33
|
+
|
|
34
|
+
console.log(
|
|
35
|
+
`House price for token ID ${tokenId}: ${ethers.formatEther(
|
|
36
|
+
housePrice
|
|
37
|
+
)} ETH`
|
|
38
|
+
);
|
|
39
|
+
return housePrice;
|
|
40
|
+
} catch (error: any) {
|
|
41
|
+
console.error(`Error getting house price for token ID ${tokenId}:`, error);
|
|
42
|
+
throw new Error(`Failed to get house price: ${error.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default getHousePrice;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { ethers, Provider } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../utils/contracts";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import { ChainId } from "../../configs/chains";
|
|
5
|
+
import { LendingPool, ReserveLibrary } from "../../typechain-types";
|
|
6
|
+
import { RawData, Reserve } from "../../custom-types";
|
|
7
|
+
|
|
8
|
+
// checked
|
|
9
|
+
async function getLendingPoolInfo(
|
|
10
|
+
chainId: ChainId,
|
|
11
|
+
address: string,
|
|
12
|
+
provider: Provider
|
|
13
|
+
) {
|
|
14
|
+
try {
|
|
15
|
+
const lendingPoolAddress = getContractAddress(chainId, "lendingpool");
|
|
16
|
+
const abi = getABI("lendingpool");
|
|
17
|
+
const lendingPoolContract = new ethers.Contract(
|
|
18
|
+
lendingPoolAddress,
|
|
19
|
+
abi,
|
|
20
|
+
provider
|
|
21
|
+
) as any as LendingPool;
|
|
22
|
+
|
|
23
|
+
const handleError =
|
|
24
|
+
(operation: string, returnType?: any) => (error: any) => {
|
|
25
|
+
if (error.code === "BAD_DATA") {
|
|
26
|
+
console.log(
|
|
27
|
+
`BAD_DATA from ${operation} - Pool empty?`,
|
|
28
|
+
error.message
|
|
29
|
+
);
|
|
30
|
+
return returnType || null;
|
|
31
|
+
}
|
|
32
|
+
throw error;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const [
|
|
36
|
+
reserve,
|
|
37
|
+
rateData,
|
|
38
|
+
normalizedIncome,
|
|
39
|
+
normalizedDebt,
|
|
40
|
+
totalVaultDeposits,
|
|
41
|
+
] = await Promise.all([
|
|
42
|
+
(lendingPoolContract.reserve() as Promise<Reserve>).catch(
|
|
43
|
+
handleError("reserve")
|
|
44
|
+
),
|
|
45
|
+
(lendingPoolContract.rateData() as Promise<RawData>).catch(
|
|
46
|
+
handleError("rateData")
|
|
47
|
+
),
|
|
48
|
+
lendingPoolContract
|
|
49
|
+
.getNormalizedIncome()
|
|
50
|
+
.catch(handleError("getNormalizedIncome", 0n)),
|
|
51
|
+
lendingPoolContract
|
|
52
|
+
.getNormalizedDebt()
|
|
53
|
+
.catch(handleError("getNormalizedDebt", 0n)),
|
|
54
|
+
lendingPoolContract
|
|
55
|
+
.totalVaultDeposits()
|
|
56
|
+
.catch(handleError("totalVaultDeposits", 0n)),
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
console.log(reserve);
|
|
60
|
+
|
|
61
|
+
// Extract data from reserve
|
|
62
|
+
const totalLiquidity: bigint = reserve?.totalLiquidity ?? 0n;
|
|
63
|
+
const totalUsage: bigint = reserve?.totalUsage ?? 0n;
|
|
64
|
+
const liquidityIndex: bigint = reserve?.liquidityIndex ?? 0n;
|
|
65
|
+
const usageIndex: bigint = reserve?.usageIndex ?? 0n;
|
|
66
|
+
|
|
67
|
+
// Compute utilization
|
|
68
|
+
let utilization = 0n;
|
|
69
|
+
if (totalLiquidity + totalUsage > 0n) {
|
|
70
|
+
utilization = (totalUsage * BigInt(1e27)) / (totalLiquidity + totalUsage);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Extract rate data
|
|
74
|
+
const currentLiquidityRate: bigint = rateData?.currentLiquidityRate ?? 0n;
|
|
75
|
+
const currentUsageRate: bigint = rateData?.currentUsageRate ?? 0n;
|
|
76
|
+
const primeRate: bigint = rateData?.primeRate ?? 0n;
|
|
77
|
+
const baseRate: bigint = rateData?.baseRate ?? 0n;
|
|
78
|
+
const optimalRate: bigint = rateData?.optimalRate ?? 0n;
|
|
79
|
+
const maxRate: bigint = rateData?.maxRate ?? 0n;
|
|
80
|
+
const optimalUtilizationRate: bigint =
|
|
81
|
+
rateData?.optimalUtilizationRate ?? 0n;
|
|
82
|
+
const protocolFeeRate: bigint = rateData?.protocolFeeRate ?? 0n;
|
|
83
|
+
|
|
84
|
+
// Compute APY
|
|
85
|
+
let apy: bigint;
|
|
86
|
+
if (utilization <= optimalUtilizationRate && optimalUtilizationRate > 0) {
|
|
87
|
+
const rateSlope = primeRate - baseRate;
|
|
88
|
+
const rateIncrease = (utilization * rateSlope) / optimalUtilizationRate;
|
|
89
|
+
apy = baseRate + rateIncrease;
|
|
90
|
+
} else {
|
|
91
|
+
const excessUtilization = utilization - optimalUtilizationRate;
|
|
92
|
+
const maxExcessUtilization = BigInt(1e27) - optimalUtilizationRate;
|
|
93
|
+
const rateSlope = maxRate - primeRate;
|
|
94
|
+
const rateIncrease =
|
|
95
|
+
(excessUtilization * rateSlope) / maxExcessUtilization;
|
|
96
|
+
apy = primeRate + rateIncrease;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let userRedeemable = 0n;
|
|
100
|
+
if (address) {
|
|
101
|
+
// Fetch user's scaled RToken balance
|
|
102
|
+
const rTokenAddress = reserve?.reserveRTokenAddress as string;
|
|
103
|
+
const rTokenABI = getABI("rtoken");
|
|
104
|
+
const rTokenContract = new ethers.Contract(
|
|
105
|
+
rTokenAddress,
|
|
106
|
+
rTokenABI,
|
|
107
|
+
provider
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const userScaledBalance = await rTokenContract
|
|
111
|
+
.balanceOf(address)
|
|
112
|
+
.catch(handleError("rToken balanceOf"));
|
|
113
|
+
|
|
114
|
+
// Compute user's redeemable balance: userRedeemable = userScaledBalance * liquidityIndex / RAY
|
|
115
|
+
userRedeemable = (userScaledBalance * liquidityIndex) / BigInt(1e27);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const result = {
|
|
119
|
+
totalLiquidity: ethers.formatEther(totalLiquidity),
|
|
120
|
+
totalBorrow: ethers.formatEther(totalUsage),
|
|
121
|
+
utilization: (Number(utilization.toString()) / 1e27).toFixed(6), // Utilization as a decimal value between 0 and 1
|
|
122
|
+
liquidityIndex: (Number(liquidityIndex.toString()) / 1e27).toFixed(6),
|
|
123
|
+
usageIndex: (Number(usageIndex.toString()) / 1e27).toFixed(6),
|
|
124
|
+
currentLiquidityRate:
|
|
125
|
+
(Number(currentLiquidityRate.toString()) / 1e25).toFixed(2) + "%",
|
|
126
|
+
currentUsageRate:
|
|
127
|
+
(Number(currentUsageRate.toString()) / 1e25).toFixed(2) + "%",
|
|
128
|
+
primeRate: (Number(primeRate.toString()) / 1e25).toFixed(2) + "%",
|
|
129
|
+
baseRate: (Number(baseRate.toString()) / 1e25).toFixed(2) + "%",
|
|
130
|
+
optimalRate: (Number(optimalRate.toString()) / 1e25).toFixed(2) + "%",
|
|
131
|
+
maxRate: (Number(maxRate.toString()) / 1e25).toFixed(2) + "%",
|
|
132
|
+
optimalUtilizationRate: (
|
|
133
|
+
Number(optimalUtilizationRate.toString()) / 1e27
|
|
134
|
+
).toFixed(6),
|
|
135
|
+
protocolFeeRate:
|
|
136
|
+
(Number(protocolFeeRate.toString()) / 1e25).toFixed(2) + "%",
|
|
137
|
+
normalizedIncome: (Number(normalizedIncome.toString()) / 1e27).toFixed(6),
|
|
138
|
+
normalizedDebt: (Number(normalizedDebt.toString()) / 1e27).toFixed(6),
|
|
139
|
+
apy: (Number(apy.toString()) / 1e25).toFixed(2) + "%",
|
|
140
|
+
userRedeemable: ethers.formatEther(userRedeemable ?? 0n),
|
|
141
|
+
totalVaultDeposits: ethers.formatEther(totalVaultDeposits),
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
console.log(result);
|
|
145
|
+
|
|
146
|
+
return result;
|
|
147
|
+
} catch (error: any) {
|
|
148
|
+
console.error("Error fetching lending pool info:", error);
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export default getLendingPoolInfo;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ethers, Provider } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../utils/contracts";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import { ChainId } from "../../configs/chains";
|
|
5
|
+
import { LendingPool } from "../../typechain-types";
|
|
6
|
+
import { Reserve } from "../../custom-types";
|
|
7
|
+
|
|
8
|
+
// The lending pool reserve contains the total liquidity of the lending pool. see getLendingPooInfo.ts
|
|
9
|
+
// @deprecated
|
|
10
|
+
async function getLendingPoolTotalLiquidity(
|
|
11
|
+
chainId: ChainId,
|
|
12
|
+
provider: Provider
|
|
13
|
+
) {
|
|
14
|
+
try {
|
|
15
|
+
const lendingPoolAddress = getContractAddress(chainId, "lendingpool");
|
|
16
|
+
const abi = getABI("lendingpool");
|
|
17
|
+
const lendingPoolContract = new ethers.Contract(
|
|
18
|
+
lendingPoolAddress,
|
|
19
|
+
abi,
|
|
20
|
+
provider
|
|
21
|
+
) as any as LendingPool;
|
|
22
|
+
|
|
23
|
+
const reserve = (await lendingPoolContract.reserve()) as Reserve;
|
|
24
|
+
const totalLiquidity = reserve.totalLiquidity;
|
|
25
|
+
return totalLiquidity;
|
|
26
|
+
} catch (error: any) {
|
|
27
|
+
console.error("Error fetching total liquidity:", error);
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default getLendingPoolTotalLiquidity;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ethers, Provider } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../contracts/getContractAddress";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import { ChainId } from "../../configs/chains/index";
|
|
5
|
+
import { ERC20, LendingPool } from "../../typechain-types";
|
|
6
|
+
async function repayToLendingPool(
|
|
7
|
+
chainId: ChainId,
|
|
8
|
+
tokenId: string | number,
|
|
9
|
+
amount: bigint,
|
|
10
|
+
signer: Provider
|
|
11
|
+
) {
|
|
12
|
+
try {
|
|
13
|
+
const lendingPoolAddress = getContractAddress(chainId, "lendingpool");
|
|
14
|
+
const crvUSDAddress = getContractAddress(chainId, "rcrvusd");
|
|
15
|
+
const lendingPoolABI = getABI("lendingpool");
|
|
16
|
+
const crvUSDABI = getABI("crvusd");
|
|
17
|
+
|
|
18
|
+
const lendingPoolContract = new ethers.Contract(
|
|
19
|
+
lendingPoolAddress,
|
|
20
|
+
lendingPoolABI,
|
|
21
|
+
signer
|
|
22
|
+
) as any as LendingPool;
|
|
23
|
+
const crvUSDTokenContract = new ethers.Contract(
|
|
24
|
+
crvUSDAddress,
|
|
25
|
+
crvUSDABI,
|
|
26
|
+
signer
|
|
27
|
+
) as any as ERC20;
|
|
28
|
+
|
|
29
|
+
const approveTx = await crvUSDTokenContract.approve(
|
|
30
|
+
lendingPoolAddress,
|
|
31
|
+
amount
|
|
32
|
+
);
|
|
33
|
+
await approveTx.wait();
|
|
34
|
+
console.log(
|
|
35
|
+
`Approved lendingPoolContract to spend ${ethers.formatEther(
|
|
36
|
+
amount
|
|
37
|
+
)} crvUSD`
|
|
38
|
+
);
|
|
39
|
+
const tx = await lendingPoolContract.repay(amount);
|
|
40
|
+
const receipt = await tx.wait();
|
|
41
|
+
|
|
42
|
+
console.log(`Repaid ${ethers.formatEther(amount)} for NFT #${tokenId}`);
|
|
43
|
+
console.log(`Transaction hash: ${receipt?.hash}`);
|
|
44
|
+
|
|
45
|
+
return receipt;
|
|
46
|
+
} catch (error: any) {
|
|
47
|
+
console.error("Error in repayToLendingPool:", error);
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default repayToLendingPool;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ethers, Signer } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../contracts/getContractAddress";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import estimateGasPrice from "../../methods/commons/estimateGasPrice";
|
|
5
|
+
import { ChainId } from "../../configs/chains";
|
|
6
|
+
import { ERC20, LendingPool } from "../../typechain-types";
|
|
7
|
+
async function withdrawFromLendingPool(
|
|
8
|
+
chainId: ChainId,
|
|
9
|
+
amount: bigint,
|
|
10
|
+
signer: Signer
|
|
11
|
+
) {
|
|
12
|
+
try {
|
|
13
|
+
const lendingPoolAddress = getContractAddress(chainId, "lendingpool");
|
|
14
|
+
const rtokenAddress = getContractAddress(chainId, "rtoken");
|
|
15
|
+
const lendingPoolABI = getABI("lendingpool");
|
|
16
|
+
const assetABI = getABI("rtoken");
|
|
17
|
+
|
|
18
|
+
const lendingPoolContract = new ethers.Contract(
|
|
19
|
+
lendingPoolAddress,
|
|
20
|
+
lendingPoolABI,
|
|
21
|
+
signer
|
|
22
|
+
) as any as LendingPool;
|
|
23
|
+
const rTokenContract = new ethers.Contract(
|
|
24
|
+
rtokenAddress,
|
|
25
|
+
assetABI,
|
|
26
|
+
signer
|
|
27
|
+
) as any as ERC20;
|
|
28
|
+
|
|
29
|
+
const amountInWei = ethers.parseEther(amount.toString());
|
|
30
|
+
const { maxFeePerGas } = await estimateGasPrice(signer);
|
|
31
|
+
|
|
32
|
+
const userBalance = await rTokenContract.balanceOf(
|
|
33
|
+
await signer.getAddress()
|
|
34
|
+
);
|
|
35
|
+
if (userBalance < amount) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Insufficient rcrvUSD balance. Available: ${ethers.formatEther(
|
|
38
|
+
userBalance
|
|
39
|
+
)}, Requested: ${ethers.formatEther(amount)}`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const approveTx = await rTokenContract.approve(
|
|
44
|
+
lendingPoolAddress,
|
|
45
|
+
amountInWei
|
|
46
|
+
);
|
|
47
|
+
await approveTx.wait();
|
|
48
|
+
console.log(`Approved LendingPool to spend ${amount} rcrvUSD`);
|
|
49
|
+
|
|
50
|
+
// const withdraw = await lendingPoolContract.withdraw(amountInWei.toString(), {
|
|
51
|
+
// maxFeePerGas,
|
|
52
|
+
// nonce: await signer.getNonce()
|
|
53
|
+
// });
|
|
54
|
+
|
|
55
|
+
const tx = await lendingPoolContract.withdraw(amountInWei);
|
|
56
|
+
const receipt = await tx.wait();
|
|
57
|
+
|
|
58
|
+
console.log(`Withdrawn ${amount} from Lending Pool`);
|
|
59
|
+
console.log(`Transaction hash: ${receipt?.hash}`);
|
|
60
|
+
|
|
61
|
+
return receipt;
|
|
62
|
+
} catch (error: any) {
|
|
63
|
+
console.error("Error in withdrawFromLendingPool:", error);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export default withdrawFromLendingPool;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ethers, Signer } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../utils/contracts";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import { ChainId } from "../../configs/chains/index";
|
|
5
|
+
import { LendingPool } from "../../typechain-types";
|
|
6
|
+
|
|
7
|
+
async function withdrawNFTFromLendingPool(
|
|
8
|
+
chainId: ChainId,
|
|
9
|
+
tokenId: number,
|
|
10
|
+
signer: Signer
|
|
11
|
+
) {
|
|
12
|
+
if (!signer) {
|
|
13
|
+
throw new Error("Wallet not connected");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const lendingPoolAddress = getContractAddress(chainId, "lendingpool");
|
|
18
|
+
const lendingPoolABI = getABI("lendingpool");
|
|
19
|
+
|
|
20
|
+
const lendingPoolContract = new ethers.Contract(
|
|
21
|
+
lendingPoolAddress,
|
|
22
|
+
lendingPoolABI,
|
|
23
|
+
signer
|
|
24
|
+
) as any as LendingPool;
|
|
25
|
+
|
|
26
|
+
const tx = await lendingPoolContract.withdrawNFT(tokenId);
|
|
27
|
+
await tx.wait();
|
|
28
|
+
|
|
29
|
+
console.log(`Withdrawn NFT with token ID ${tokenId} from lending pool`);
|
|
30
|
+
return tx;
|
|
31
|
+
} catch (error: any) {
|
|
32
|
+
console.error("Error withdrawing NFT from lending pool:", error);
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Failed to withdraw NFT from lending pool: ${error.message}`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default withdrawNFTFromLendingPool;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ethers, Provider } from "ethers";
|
|
2
|
+
import { getContractAddress } from "../../utils/contracts";
|
|
3
|
+
import { getABI } from "../../utils/artifacts";
|
|
4
|
+
import { ChainId } from "../../configs/chains/index";
|
|
5
|
+
|
|
6
|
+
async function getLiquidityPoolInfo(
|
|
7
|
+
chainId: ChainId,
|
|
8
|
+
address: string,
|
|
9
|
+
provider: Provider
|
|
10
|
+
) {
|
|
11
|
+
try {
|
|
12
|
+
const liquidityPoolAddress = getContractAddress(chainId, "liquiditypool");
|
|
13
|
+
const abi = getABI("liquiditypool");
|
|
14
|
+
const liquidityPoolContract = new ethers.Contract(
|
|
15
|
+
liquidityPoolAddress,
|
|
16
|
+
abi,
|
|
17
|
+
provider
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const handleError = (operation: string) => (error: any) => {
|
|
21
|
+
if (error.code === "BAD_DATA") {
|
|
22
|
+
console.log(
|
|
23
|
+
`BAD_DATA from getLiquidityPoolInfo - ${operation}:`,
|
|
24
|
+
error.message
|
|
25
|
+
);
|
|
26
|
+
return 0n;
|
|
27
|
+
}
|
|
28
|
+
throw error;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Get all markets
|
|
32
|
+
const markets = await liquidityPoolContract
|
|
33
|
+
.getMarkets()
|
|
34
|
+
.catch(handleError("getMarkets"));
|
|
35
|
+
|
|
36
|
+
const result = {
|
|
37
|
+
markets: {},
|
|
38
|
+
tvl: "0",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
for (const market of markets) {
|
|
42
|
+
const [totalLiquidity, userLiquidity, exchangeRate] = await Promise.all([
|
|
43
|
+
liquidityPoolContract
|
|
44
|
+
.getTotalLiquidity(market)
|
|
45
|
+
.catch(handleError("getTotalLiquidity")),
|
|
46
|
+
address
|
|
47
|
+
? liquidityPoolContract
|
|
48
|
+
// FIXME: pariedToken not defined.
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
.getUserLiquidity(pairedToken, address)
|
|
51
|
+
.catch(handleError("getUserLiquidity"))
|
|
52
|
+
: [0n, 0n, 0n],
|
|
53
|
+
liquidityPoolContract
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
.getExchangeRate(pairedToken)
|
|
56
|
+
.catch(handleError("getExchangeRate")),
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
result.markets[pairedToken] = {
|
|
61
|
+
totalLiquidity: {
|
|
62
|
+
raac: ethers.formatEther(totalLiquidity[0] ?? 0n),
|
|
63
|
+
paired: ethers.formatEther(totalLiquidity[1] ?? 0n),
|
|
64
|
+
},
|
|
65
|
+
userLiquidity: {
|
|
66
|
+
raac: ethers.formatEther(userLiquidity[0] ?? 0n),
|
|
67
|
+
paired: ethers.formatEther(userLiquidity[1] ?? 0n),
|
|
68
|
+
lpAmount: ethers.formatEther(userLiquidity[2] ?? 0n),
|
|
69
|
+
},
|
|
70
|
+
exchangeRate: {
|
|
71
|
+
raacPerPaired: ethers.formatEther(exchangeRate[0] ?? 0n),
|
|
72
|
+
pairedPerRaac: ethers.formatEther(exchangeRate[1] ?? 0n),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const tvl = await liquidityPoolContract
|
|
78
|
+
.getTotalValueLocked()
|
|
79
|
+
.catch(handleError("getTotalValueLocked"));
|
|
80
|
+
result.tvl = ethers.formatEther(tvl ?? 0n);
|
|
81
|
+
|
|
82
|
+
console.log("getLiquidityPoolInfo result:", result);
|
|
83
|
+
return result;
|
|
84
|
+
} catch (error: any) {
|
|
85
|
+
console.error("Error fetching liquidity pool info:", error);
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export default getLiquidityPoolInfo;
|