How to run your own liquidation bot

DeltaPrime's liquidation bots are currently on a whitelist basis. If you want to run your own liquidation bot, please reach out to us in our Discord.

Liquidation is an action of forcibly repaying part of the debt in order to bring loan back to a solvent state. It is only possible to perform this action for accounts that are insolvent (HealthRatio<1).

HealthRatio

HealthRatio used in smart contracts differs from the one displayed in the UI. Health meter presented in the UI stays inbetween 0 and 100%; 0% meaning that the account is insolvent. HealthRatio used by smart contracts is defined as ThresholdWeightedValue / Debt. Those two values can be obtained by calling the SolvencyFacetProd.sol:getThresholdWeightedValue() and SolvencyFacetProd.sol:getDebt() respectively.

function getThresholdWeightedValue() public view returns (uint256) {
function getDebt() public view returns (uint256)

Get SmartLoan address

In order to perform liquidations one first needs to obtain SmartLoan(s) address(es) which can be achieved by interacting with the SmartLoansFactoryTUP (TransparentUpgradeableProxy) contract that is deployed on the Avalanche mainnet under the address 0x3Ea9D480295A73fd2aF95b4D96c2afF88b21B03D.

The SmartLoansFactory.sol contract exposes a public getAllLoans() method that returns an array containing all SmartLoans addresses. It is also possible to obtain a SmartLoan contract address for a specific user (wallet) by calling the following method SmartLoansFactory.sol:getLoanForOwner().

function getAllLoans() public view returns (address[] memory)
function getLoanForOwner(address _owner) external view returns (address)

Get SmartLoan full status

With the use of a SmartLoan address one can call that contract's SolvencyFacetProd.sol:getFullLoanStatus() method that returns an array consisting of the following values [totalValue, debt, thresholdWeightedValue, healthRatio, isSolvent].

function getFullLoanStatus() public view returns (uint256[5] memory)

To execute a liquidation of a chosen loan one has to execute the SmartLoanLiquidationFacet.sol:liquidateLoan() method.

function liquidateLoan(bytes32[] memory assetsToRepay, uint256[] memory amountsToRepay, uint256 _liquidationBonusPercent)

The assetsToRepay parameter specifies which assets are going to be repaid back to the lending pools. The amountsToRepay parameter defines in what amounts should the selected assetsToRepay be repaid. The _liquidationBonusPercent parameter defines the liquidation bonus % value. It's value must stay inbetween 0 and _MAX_LIQUIDATION_BONUS. _MAX_LIQUIDATION_BONUS can be can be obtained by calling the SmartLoanLiquidationFacet.sol:getMaxLiquidationBonus() method.

function getMaxLiquidationBonus() public pure returns (uint256)

The above values should be calculated in a way that results in a loan which HealthRatio ∈ <1;_MAX_HEALTH_AFTER_LIQUIDATION>.

_MAX_HEALTH_AFTER_LIQUIDATION can be obtained by calling the SmartLoanLiquidationFacet.sol:getMaxHealthAfterLiquidation()method.

function getMaxHealthAfterLiquidation() public pure returns (uint256)

Unstake positions

By default no swaps or unstaking takes place during a liqudiation. The liquidator specifies the repay amounts, supplies tokens if needed and at the end the liquidator receives tokens from the account being liquidated equal in the USD value to the USD value of the tokens supplied (+ the bonus fee). However, in some cases the staked positions are non-transferrable (e.g. VectorFinance). For this reason it is possible to unstake one's staked positions despite not being an owner of that given loan. This is only possible in a scenario where the loan is already insolvent and serves the purpose of preparing the loan to be further liquidated. You can obtain loan's staked positions using the following method SmartLoanViewFacet.sol:getStakedPositions(). Use the balanceSelector & unstakeSelector methods selectors to check the balance of a staked position and to execute the relevant unstake() method respectively.

function getStakedPositions() external view returns (IStakingPositions.StakedPosition[] memory _positions)

struct StakedPosition {
        address asset;
        bytes32 symbol;
        bytes32 identifier;
        bytes4 balanceSelector;
        bytes4 unstakeSelector;
    }

Example liquidation bot implementation

An example javascript implementation of a liquidation bot can be found here.

This implementation uses a flashloan to borrow tokens needed to repay the loan prior to the liquidation but it is also possible to write a liquidation bot that uses solely the liquidator's funds.

Last updated