Skip to content

Commit

Permalink
Merge pull request #108 from ionicprotocol/feat/liquidation-bot-mode
Browse files Browse the repository at this point in the history
Liquidation bot refactoring for UniV3 and Mode
  • Loading branch information
rhlsthrm authored Feb 1, 2024
2 parents 980f91e + 6625c1a commit 8b4798d
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 49 deletions.
8 changes: 4 additions & 4 deletions packages/chains/src/mode/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { ethers } from "ethers";
import { assets } from "./assets";

const chainAddresses: ChainAddresses = {
PAIR_INIT_HASH: "",
PAIR_INIT_HASH: "", // TODO is this used anywhere?
STABLE_TOKEN: underlying(assets, assetSymbols.USDC),
UNISWAP_V2_ROUTER: ethers.constants.AddressZero,
UNISWAP_V2_FACTORY: ethers.constants.AddressZero,
UNISWAP_V2_ROUTER: "0x5D61c537393cf21893BE619E36fC94cd73C77DD3",
UNISWAP_V2_FACTORY: "0xc02155946dd8c89d3d3238a6c8a64d04e2cd4500",
UNISWAP_V3: {
FACTORY: "0xC33Ce0058004d44E7e1F366E5797A578fDF38584",
PAIR_INIT_HASH: "0x3e03ddab0aa29c12c46cd283f9cf8c6800eb7ea3c6530a382474bac82333f2e0",
QUOTER_V2: "0x7Fd569b2021850fbA53887dd07736010aCBFc787" //
QUOTER_V2: "0x7Fd569b2021850fbA53887dd07736010aCBFc787"
},
UNISWAP_V3_ROUTER: "0xC9Adff795f46105E53be9bbf14221b1C9919EE25",
W_BTC_TOKEN: underlying(assets, assetSymbols.WBTC),
Expand Down
38 changes: 18 additions & 20 deletions packages/sdk/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { getCgPrice } from "../chainDeploy/helpers/getCgPrice";
import {
configureAddressesProviderAddresses,
configureIonicLiquidator,
deployIonicLiquidator,
deployIonicUniV3Liquidator
deployIonicLiquidator
} from "../chainDeploy/helpers/liquidators/ionicLiquidator";
import { configureLiquidatorsRegistry } from "../chainDeploy/helpers/liquidators/registry";
import { AddressesProvider } from "../typechain/AddressesProvider";
Expand Down Expand Up @@ -484,25 +483,24 @@ const func: DeployFunction = async ({ run, ethers, getNamedAccounts, deployments
////

//// Liquidator
let liquidatorContractName;

if (chainId !== 34443) {
liquidatorContractName = await deployIonicLiquidator({
run,
ethers,
getNamedAccounts,
deployments,
deployConfig: chainDeployParams
});
} else {
liquidatorContractName = await deployIonicUniV3Liquidator({
run,
ethers,
getNamedAccounts,
deployments,
deployConfig: chainDeployParams
});
}
// if (chainId !== 34443) {
const liquidatorContractName = await deployIonicLiquidator({
run,
ethers,
getNamedAccounts,
deployments,
deployConfig: chainDeployParams
});
// } else {
// liquidatorContractName = await deployIonicUniV3Liquidator({
// run,
// ethers,
// getNamedAccounts,
// deployments,
// deployConfig: chainDeployParams
// });
// }

///

Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/deployments/mode/IonicUniV3Liquidator.json
Original file line number Diff line number Diff line change
Expand Up @@ -579,4 +579,4 @@
"storage": [],
"types": null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1062,4 +1062,4 @@
"transferOwnership(address)": "f2fde38b",
"uniswapV3FlashCallback(uint256,uint256,bytes)": "e9cbafb0"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1477,4 +1477,4 @@
"transferOwnership(address)": "f2fde38b",
"uniswapV3Fees(address,address)": "398cd955"
}
}
}
14 changes: 11 additions & 3 deletions packages/sdk/src/IonicSdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { BigNumber, Contract, Signer, utils } from "ethers";

import AddressesProviderArtifact from "../../artifacts/AddressesProvider.sol/AddressesProvider.json";
import CTokenFirstExtensionArtifact from "../../artifacts/CTokenFirstExtension.sol/CTokenFirstExtension.json";
import EIP20InterfaceArtifact from "../../artifacts/EIP20Interface.sol/EIP20Interface.json";
import FeeDistributorArtifact from "../../artifacts/FeeDistributor.sol/FeeDistributor.json";
Expand All @@ -25,6 +26,7 @@ import PoolDirectoryArtifact from "../../artifacts/PoolDirectory.sol/PoolDirecto
import PoolLensArtifact from "../../artifacts/PoolLens.sol/PoolLens.json";
import PoolLensSecondaryArtifact from "../../artifacts/PoolLensSecondary.sol/PoolLensSecondary.json";
import UnitrollerArtifact from "../../artifacts/Unitroller.sol/Unitroller.json";
import { AddressesProvider } from "../../typechain/AddressesProvider";
import { CTokenFirstExtension } from "../../typechain/CTokenFirstExtension";
import { EIP20Interface } from "../../typechain/EIP20Interface";
import { FeeDistributor } from "../../typechain/FeeDistributor.sol/FeeDistributor";
Expand Down Expand Up @@ -67,6 +69,7 @@ export type StaticContracts = {
PoolLens: PoolLens;
PoolLensSecondary: PoolLensSecondary;
IonicLiquidator: ILiquidator;
AddressesProvider: AddressesProvider;
[contractName: string]: Contract;
};

Expand Down Expand Up @@ -138,9 +141,9 @@ export class IonicBase {
this.provider
) as PoolLensSecondary,
IonicLiquidator: new Contract(
this.chainId == 34443
? this.chainDeployment.IonicUniV3Liquidator.address
: this.chainDeployment.IonicLiquidator.address,
// this.chainId == 34443
// ? this.chainDeployment.IonicUniV3Liquidator.address :
this.chainDeployment.IonicLiquidator.address,
IonicLiquidatorArtifact.abi,
this.provider
) as ILiquidator,
Expand All @@ -154,6 +157,11 @@ export class IonicBase {
IonicFlywheelLensRouterArtifact.abi,
this.provider
) as IonicFlywheelLensRouter,
AddressesProvider: new Contract(
this.chainDeployment.AddressesProvider.address,
AddressesProviderArtifact.abi,
this.provider
) as AddressesProvider,
...this._contracts
};
}
Expand Down
71 changes: 54 additions & 17 deletions packages/sdk/src/modules/liquidation/getPotentialLiquidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { BigNumber, BytesLike, constants, utils } from "ethers";

import { ICErc20 } from "../../../typechain/CTokenInterfaces.sol/ICErc20";
import { IUniswapV2Factory__factory } from "../../../typechain/factories/IUniswapV2Factory__factory";
import { IUniswapV3Factory__factory } from "../../../typechain/factories/IUniswapV3Factory__factory";
import { LiquidatorsRegistry__factory } from "../../../typechain/factories/LiquidatorsRegistry__factory";
import { LiquidatorsRegistry } from "../../../typechain/LiquidatorsRegistry";
import { IonicSdk } from "../../IonicSdk";

import { ChainLiquidationConfig } from "./config";
Expand Down Expand Up @@ -142,32 +145,66 @@ export default async function getPotentialLiquidation(
);

let flashSwapPair;
const uniswapV2Factory = IUniswapV2Factory__factory.connect(
sdk.chainSpecificAddresses.UNISWAP_V2_FACTORY,
sdk.provider
);

if (flashSwapFundingToken != sdk.chainConfig.chainAddresses.W_TOKEN) {
flashSwapPair = await uniswapV2Factory.callStatic.getPair(
flashSwapFundingToken,
sdk.chainConfig.chainAddresses.W_TOKEN
);
} else {
// flashSwapFundingToken is the W_TOKEN
flashSwapPair = await uniswapV2Factory.callStatic.getPair(
flashSwapFundingToken,
sdk.chainConfig.chainAddresses.STABLE_TOKEN
let tokenA, tokenB;
//if (sdk.chainId == 34443) {
if (false) {
const uniV3Factory = IUniswapV3Factory__factory.connect(
sdk.chainSpecificAddresses.UNISWAP_V3?.FACTORY || "0xC33Ce0058004d44E7e1F366E5797A578fDF38584",
sdk.provider
);

if (flashSwapFundingToken != sdk.chainConfig.chainAddresses.W_TOKEN) {
tokenA = flashSwapFundingToken;
tokenB = sdk.chainConfig.chainAddresses.W_TOKEN;
} else {
// flashSwapFundingToken is the W_TOKEN
tokenA = flashSwapFundingToken;
tokenB = sdk.chainConfig.chainAddresses.STABLE_TOKEN;
}
// query the configured univ3 pool fee from the liquidators registry
const lrAddress = await sdk.contracts.AddressesProvider.getAddress("LiquidatorsRegistry");
const liquidatorsRegistry = LiquidatorsRegistry__factory.connect(lrAddress, sdk.provider) as LiquidatorsRegistry;
const fee = await liquidatorsRegistry.callStatic.uniswapV3Fees(tokenA, tokenB);

flashSwapPair = await uniV3Factory.callStatic.getPool(tokenA, tokenB, fee);
if (tokenPath.indexOf(flashSwapPair) > 0) {
// in case the Uniswap pair LP token is on the path of redemptions, we should use
// another pair because reentrancy checks prevent us from using the pair
// when inside the execution of a flash swap from the same pair
tokenA = flashSwapFundingToken;
tokenB = sdk.chainConfig.chainAddresses.W_BTC_TOKEN;
flashSwapPair = await uniV3Factory.callStatic.getPool(tokenA, tokenB, fee);
} else {
sdk.logger.info(`flash swap pair ${flashSwapPair} is not on the token path ${tokenPath}`);
}
} else {
const uniswapV2Factory = IUniswapV2Factory__factory.connect(
sdk.chainSpecificAddresses.UNISWAP_V2_FACTORY,
sdk.provider
);

if (flashSwapFundingToken != sdk.chainConfig.chainAddresses.W_TOKEN) {
flashSwapPair = await uniswapV2Factory.callStatic.getPair(
flashSwapFundingToken,
sdk.chainConfig.chainAddresses.W_BTC_TOKEN
sdk.chainConfig.chainAddresses.W_TOKEN
);
} else {
sdk.logger.info(`flash swap pair ${flashSwapPair} is not on the token path ${tokenPath}`);
// flashSwapFundingToken is the W_TOKEN
flashSwapPair = await uniswapV2Factory.callStatic.getPair(
flashSwapFundingToken,
sdk.chainConfig.chainAddresses.STABLE_TOKEN
);
if (tokenPath.indexOf(flashSwapPair) > 0) {
// in case the Uniswap pair LP token is on the path of redemptions, we should use
// another pair because reentrancy checks prevent us from using the pair
// when inside the execution of a flash swap from the same pair
flashSwapPair = await uniswapV2Factory.callStatic.getPair(
flashSwapFundingToken,
sdk.chainConfig.chainAddresses.W_BTC_TOKEN
);
} else {
sdk.logger.info(`flash swap pair ${flashSwapPair} is not on the token path ${tokenPath}`);
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/sdk/tests-mocha/IonicSdk/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ describe("Ionic Index", () => {
PoolLens: { abi: [], address: mkAddress("0xbcc") },
PoolLensSecondary: { abi: [], address: mkAddress("0xdcc") },
IonicLiquidator: { abi: [], address: mkAddress("0xecc") },
JumpRateModel: { abi: [], address: mkAddress("0xaac") }
JumpRateModel: { abi: [], address: mkAddress("0xaac") },
AddressesProvider: { abi: [], address: mkAddress("0xaad") }
};
ionicBase = new IonicBase(mockProvider, ganache);
ionicBase.contracts = { PoolDirectory: mockContract as unknown as PoolDirectory };
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/tests-mocha/modules/FusePools.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ describe("FusePools", () => {
FusePools = withPools(IonicBase);

ganache.chainDeployments = {
AddressesProvider: { abi: [], address: mkAddress("0xabb") },
CErc20Delegate: { abi: [], address: mkAddress("0xabc") },
CErc20PluginDelegate: { abi: [], address: CErc20PluginDelegateAddress },
CErc20PluginRewardsDelegate: { abi: [], address: mkAddress("0xabc") },
Expand Down

0 comments on commit 8b4798d

Please sign in to comment.