@descent-protocol/sdk
Version:
A Typescript library for interacting with the Descent Protocol
237 lines (197 loc) • 6.5 kB
text/typescript
import {
ethers,
BigNumberish,
AddressLike,
formatUnits,
NonceManager,
parseUnits,
parseEther,
formatEther,
Signer,
AbiCoder,
} from 'ethers';
import { ICollateral, IContract } from '../types';
import { Transaction } from '../libs/transactions';
import { getContractAddress } from '../contracts/getContractAddresses';
import { Internal } from '../libs/internal';
import {
Currency__factory,
VaultGetters__factory,
VaultRouter__factory,
Vault__factory,
} from '../generated/factories';
import { getxNGNBalance } from '../libs/utils';
import { Contract } from '../contracts';
export enum VaultHealthFactor {
UNSAFE = 'UNSAFE',
SAFE = 'SAFE',
}
export enum VaultOperations {
Invalid = 0,
// Vault operations
DepositCollateral = 1,
WithdrawCollateral = 2,
MintCurrency = 3,
BurnCurrency = 4,
// Permit2 operations
Permit2_PermitTransferFrom = 5,
Permit2_Permit = 5,
Permit2_TransferFrom = 6,
/// ERC20 Operations
ERC20_Permit = 7,
ERC20_TransferFrom = 8,
}
const setupVault = async (
owner: string,
chainId: string,
transaction: Transaction,
internal: Internal,
) => {
const vaultRouterAddress: any = getContractAddress('VaultRouter', chainId);
// build transaction object
const to: any = getContractAddress('Vault', chainId);
let iface = internal.getInterface(Vault__factory.abi);
const data = iface.encodeFunctionData('rely', [vaultRouterAddress]);
const txConfig = await internal.getTransactionConfig({
from: owner,
to,
data: data,
});
const relyResult = await transaction.send(txConfig, {});
return relyResult;
};
const collateralizeVault = async (
amount: string,
collateral: ICollateral,
owner: string,
chainId: string,
transaction: Transaction,
internal: Internal,
) => {
const collateralAddress: any = getContractAddress(collateral, chainId);
const _amount = BigInt(amount) * BigInt(1e6);
// build transaction object
const to: any = getContractAddress('Vault', chainId);
let iface = internal.getInterface(Vault__factory.abi);
const data = iface.encodeFunctionData('depositCollateral', [collateralAddress, owner, _amount]);
const txConfig = await internal.getTransactionConfig({
from: owner,
to,
data: data,
});
const depositResResult = await transaction.send(txConfig, {});
return depositResResult;
};
const withdrawCollateral = async (
amount: string,
collateral: ICollateral,
owner: string,
chainId: string,
transaction: Transaction,
internal: Internal,
signer: Signer,
) => {
const collateralAddress: any = getContractAddress(collateral, chainId);
const vaultContractAddress: any = getContractAddress('Vault', chainId);
const vaultGetterAddress: any = getContractAddress('VaultGetters', chainId);
const vaultGetterContract = Contract(vaultGetterAddress, VaultGetters__factory.abi, signer);
const _amount = BigInt(amount) * BigInt(1e6);
const to: any = getContractAddress('Vault', chainId);
let iface = internal.getInterface(Vault__factory.abi);
const maxWithdrawable = await vaultGetterContract.getMaxWithdrawable(
vaultContractAddress,
collateralAddress,
owner,
);
const formattedMaxWithdrawable = formatUnits((await maxWithdrawable).toString(), 6);
if (Number(amount) > Number(formattedMaxWithdrawable.toString())) {
throw new Error(' Withdrawal amount is more than available collateral balance');
}
const recepientAddress = owner;
// build transaction object
const data = iface.encodeFunctionData('withdrawCollateral', [
collateralAddress,
owner,
recepientAddress,
_amount,
]);
const txConfig = await internal.getTransactionConfig({
from: owner,
to,
data: data,
});
const withdrawResResult = await transaction.send(txConfig, {});
return withdrawResResult;
};
const mintCurrency = async (
amount: string,
collateral: ICollateral,
owner: string,
chainId: string,
transaction: Transaction,
internal: Internal,
signer: Signer,
) => {
const collateralAddress: any = getContractAddress(collateral, chainId);
const vaultContractAddress: any = getContractAddress('Vault', chainId);
const vaultGetterAddress: any = getContractAddress('VaultGetters', chainId);
const vaultGetterContract = Contract(vaultGetterAddress, VaultGetters__factory.abi, signer);
const _amount = BigInt(amount) * BigInt(1e18);
const maxBorrowable = await vaultGetterContract.getMaxBorrowable(
vaultContractAddress,
collateralAddress,
owner,
);
const formattedmaxBorrowable = formatEther((await maxBorrowable).toString());
if (Number(amount) > Number(formattedmaxBorrowable)) {
throw new Error(' Borrow amount is more than available currency borrowable');
}
const recepientAddress = owner;
// build transaction object
const to: any = getContractAddress('Vault', chainId);
let iface = internal.getInterface(Vault__factory.abi);
const data = iface.encodeFunctionData('mintCurrency', [
collateralAddress,
owner,
recepientAddress,
_amount,
]);
const txConfig = await internal.getTransactionConfig({
from: owner,
to,
data: data,
});
const mintResResult = await transaction.send(txConfig, {});
return mintResResult;
};
const burnCurrency = async (
amount: string,
collateral: ICollateral,
owner: string,
chainId: string,
transaction: Transaction,
internal: Internal,
signer: Signer,
) => {
const collateralAddress: any = getContractAddress(collateral, chainId);
const currencyContractAddress: any = getContractAddress('Currency', chainId);
const currencyContract = Contract(currencyContractAddress, Currency__factory.abi, signer);
const _amount = BigInt(amount) * BigInt(1e18);
const balance = await currencyContract.balanceOf(owner);
const formattedBalance = await formatEther(balance.toString());
if (Number(amount) > Number(formattedBalance.toString())) {
throw new Error('Payback xNGN: Insufficient funds');
}
// build transaction object
const to: any = getContractAddress('Vault', chainId);
let iface = internal.getInterface(Vault__factory.abi);
const data = iface.encodeFunctionData('burnCurrency', [collateralAddress, owner, _amount]);
const txConfig = await internal.getTransactionConfig({
from: owner,
to,
data: data,
});
const burnResult = await transaction.send(txConfig, {});
return burnResult;
};
export { collateralizeVault, withdrawCollateral, mintCurrency, burnCurrency, setupVault };