swaps nativeToken => anyToken use exchangeBalance as a priority; generateSwapCalldata now also returns eth value for transaction

This commit is contained in:
lomonoshka
2023-11-30 14:15:49 +04:00
parent 982ec94d40
commit e0acb78d4f
3 changed files with 204 additions and 80 deletions

View File

@@ -1,9 +1,11 @@
import { ERC20__factory, type Exchange } from '@orionprotocol/contracts/lib/ethers-v6/index.js';
import type { BigNumber } from 'bignumber.js';
import { ethers } from 'ethers';
import { INTERNAL_PROTOCOL_PRECISION, NATIVE_CURRENCY_PRECISION } from '../constants/index.js';
import type { Aggregator } from '../services/Aggregator/index.js';
import denormalizeNumber from './denormalizeNumber.js';
import { ERC20__factory, Exchange__factory, type Exchange } from "@orionprotocol/contracts/lib/ethers-v6/index.js";
import type { BigNumber } from "bignumber.js";
import { ZeroAddress, ethers } from "ethers";
import { INTERNAL_PROTOCOL_PRECISION, NATIVE_CURRENCY_PRECISION } from "../constants/index.js";
import type { Aggregator } from "../services/Aggregator/index.js";
import denormalizeNumber from "./denormalizeNumber.js";
import type { AddressLike } from "ethers";
import { addressLikeToString } from "./addressLikeToString.js";
export default async function getBalance(
aggregator: Aggregator,
@@ -11,7 +13,7 @@ export default async function getBalance(
assetAddress: string,
walletAddress: string,
exchangeContract: Exchange,
provider: ethers.Provider,
provider: ethers.Provider
) {
const assetIsNativeCryptocurrency = assetAddress === ethers.ZeroAddress;
@@ -30,7 +32,10 @@ export default async function getBalance(
denormalizedAssetInWalletBalance = denormalizeNumber(assetWalletBalance, BigInt(NATIVE_CURRENCY_PRECISION));
}
const assetContractBalance = await exchangeContract.getBalance(assetAddress, walletAddress);
const denormalizedAssetInContractBalance = denormalizeNumber(assetContractBalance, BigInt(INTERNAL_PROTOCOL_PRECISION));
const denormalizedAssetInContractBalance = denormalizeNumber(
assetContractBalance,
BigInt(INTERNAL_PROTOCOL_PRECISION)
);
const denormalizedAssetLockedBalanceResult = await aggregator.getLockedBalance(walletAddress, assetName);
if (denormalizedAssetLockedBalanceResult.isErr()) {
throw new Error(denormalizedAssetLockedBalanceResult.error.message);
@@ -42,21 +47,130 @@ export default async function getBalance(
};
}
export async function getWalletBalance(
assetAddress: string,
walletAddress: string,
async function getExchangeBalanceERC20(
tokenAddress: AddressLike,
walletAddress: AddressLike,
exchangeAddress: AddressLike,
provider: ethers.Provider,
convertToNativeDecimals = true
) {
const assetIsNativeCryptocurrency = assetAddress === ethers.ZeroAddress;
walletAddress = await addressLikeToString(walletAddress);
exchangeAddress = await addressLikeToString(exchangeAddress);
tokenAddress = await addressLikeToString(tokenAddress);
let assetWalletBalance: bigint | undefined;
const exchange = <Exchange>Exchange__factory.connect(exchangeAddress, provider)
const exchangeBalance = await exchange.getBalance(tokenAddress, walletAddress);
if (!assetIsNativeCryptocurrency) {
const assetContract = ERC20__factory.connect(assetAddress, provider);
assetWalletBalance = await assetContract.balanceOf(walletAddress);
} else {
assetWalletBalance = await provider.getBalance(walletAddress);
if (convertToNativeDecimals) {
const tokenContract = ERC20__factory.connect(tokenAddress, provider);
const decimals = await tokenContract.decimals();
const convertedExchangeBalance = (exchangeBalance * BigInt(10) ** decimals) / BigInt(10) ** 8n;
return convertedExchangeBalance;
}
return assetWalletBalance
return exchangeBalance;
}
async function getExchangeBalanceNative(
walletAddress: AddressLike,
exchangeAddress: AddressLike,
provider: ethers.Provider,
convertToNativeDecimals = true
) {
walletAddress = await addressLikeToString(walletAddress);
exchangeAddress = await addressLikeToString(exchangeAddress);
const exchange = <Exchange>Exchange__factory.connect(exchangeAddress, provider)
const exchangeBalance = await exchange.getBalance(ZeroAddress, walletAddress);
if (convertToNativeDecimals) {
const convertedExchangeBalance = (exchangeBalance * BigInt(10) ** 18n) / BigInt(10) ** 8n;
return convertedExchangeBalance;
}
return exchangeBalance;
}
export async function getExchangeBalance(
tokenAddress: AddressLike,
walletAddress: AddressLike,
exchangeAddress: AddressLike,
provider: ethers.Provider,
convertToNativeDecimals = true
) {
walletAddress = await addressLikeToString(walletAddress);
tokenAddress = await addressLikeToString(tokenAddress);
if (typeof tokenAddress === "string" && tokenAddress === ZeroAddress) {
return getExchangeBalanceNative(walletAddress, exchangeAddress, provider, convertToNativeDecimals);
} else {
return getExchangeBalanceERC20(tokenAddress, walletAddress, exchangeAddress, provider, convertToNativeDecimals);
}
}
async function getWalletBalanceERC20(
tokenAddress: AddressLike,
walletAddress: AddressLike,
provider: ethers.Provider,
convertToExchangeDecimals = false
) {
walletAddress = await addressLikeToString(walletAddress);
tokenAddress = await addressLikeToString(tokenAddress);
const tokenContract = ERC20__factory.connect(tokenAddress, provider);
let walletBalance = await tokenContract.balanceOf(walletAddress);
if (convertToExchangeDecimals) {
const tokenContract = ERC20__factory.connect(tokenAddress, provider);
const decimals = await tokenContract.decimals();
const convertedNativeBalance = (walletBalance * BigInt(10) ** 8n) / BigInt(10) ** decimals;
return convertedNativeBalance;
}
return walletBalance;
}
async function getWalletBalanceNative(
walletAddress: AddressLike,
provider: ethers.Provider,
convertToExchangeDecimals = false
) {
walletAddress = await addressLikeToString(walletAddress);
const nativeBalance = await provider.getBalance(walletAddress);
if (convertToExchangeDecimals) {
const convertedNativeBalance = (nativeBalance * BigInt(10) ** 8n) / BigInt(10) ** 18n;
return convertedNativeBalance;
}
return nativeBalance;
}
export async function getWalletBalance(
tokenAddress: AddressLike,
walletAddress: AddressLike,
provider: ethers.Provider,
convertToExchangeDecimals = false
) {
if (typeof tokenAddress === "string" && tokenAddress === ZeroAddress) {
return getWalletBalanceNative(walletAddress, provider, convertToExchangeDecimals);
} else {
return getWalletBalanceERC20(tokenAddress, walletAddress, provider, convertToExchangeDecimals);
}
}
export async function getTotalBalance(
tokenAddress: AddressLike,
walletAddress: AddressLike,
exchangeAddress: AddressLike,
provider: ethers.Provider,
convertToNativeDecimals = true
) {
const walletBalance = await getWalletBalance(tokenAddress, walletAddress, provider, !convertToNativeDecimals);
const exchangeBalance = await getExchangeBalance(
tokenAddress,
walletAddress,
exchangeAddress,
provider,
convertToNativeDecimals
);
return walletBalance + exchangeBalance;
}