feat: debt bridge getGasCost granularity and cleanup

This commit is contained in:
gitpusha 2020-11-10 16:52:38 +01:00 committed by Luis Schliesske
parent de8ad63dda
commit 35cdd3f185
21 changed files with 233 additions and 191 deletions

View File

@ -36,11 +36,11 @@ Debt Bridge is a financial process that aims to make the user position safer. In
### Full Refinancing from Maker's Vault to Compound. ### Full Refinancing from Maker's Vault to Compound.
Based on the [debt bridge](https://docs.instadapp.io/usecases/debt-bridge/) documentation of Instadapp, we automated this process by adding two connectors `ConnectGelatoDataForFullRefinance`, `ConnectGelatoProviderPayment` and a Gelato condition contract. Based on the [debt bridge](https://docs.instadapp.io/usecases/debt-bridge/) documentation of Instadapp, we automated this process by adding two connectors `ConnectGelatoDataFullRefinanceMaker`, `ConnectGelatoProviderPayment` and a Gelato condition contract.
- `ConditionMakerVaultIsSafe.sol`: determine if a specific vault is on an unsafe position. - `ConditionMakerVaultIsSafe.sol`: determine if a specific vault is on an unsafe position.
- `ConnectGelatoDataForFullRefinance.sol`: generates the required data which will be assigned to the different inputs needed by `ConnectMaker` and `ConnectCompound`. Examples are the amount of DAI to pay back or the amount of Ether to withdraw from Maker. He will create the chain of connectors call needed to perform the debt refinance, he will generate the data wanted by the flashloan connector and he will call this flashloan connector through the cast function of Dsa. - `ConnectGelatoDataFullRefinanceMaker.sol`: generates the required data which will be assigned to the different inputs needed by `ConnectMaker` and `ConnectCompound`. Examples are the amount of DAI to pay back or the amount of Ether to withdraw from Maker. He will create the chain of connectors call needed to perform the debt refinance, he will generate the data wanted by the flashloan connector and he will call this flashloan connector through the cast function of Dsa.
- `ConnectGelatoProviderPayment.sol`: makes sure part of the moved collateral is used to pay the Gelato provider for the incurred transaction fee. The Gelato Provider will in turn pay the executor who executed the task. - `ConnectGelatoProviderPayment.sol`: makes sure part of the moved collateral is used to pay the Gelato provider for the incurred transaction fee. The Gelato Provider will in turn pay the executor who executed the task.

View File

@ -14,4 +14,5 @@ address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
// Insta Pool // Insta Pool
address constant INSTA_POOL_RESOLVER = 0xa004a5afBa04b74037E9E52bA1f7eb02b5E61509; address constant INSTA_POOL_RESOLVER = 0xa004a5afBa04b74037E9E52bA1f7eb02b5E61509;
uint256 constant ROUTE_1_3_TOLERANCE = 1005e15;

View File

@ -29,7 +29,7 @@ import {
_encodedWithdrawMakerVault, _encodedWithdrawMakerVault,
_encodeOpenMakerVault, _encodeOpenMakerVault,
_encodedDepositMakerVault, _encodedDepositMakerVault,
_encodeBorrowDaiMakerVault _encodeBorrowMakerVault
} from "../../functions/InstaDapp/connectors/FConnectMaker.sol"; } from "../../functions/InstaDapp/connectors/FConnectMaker.sol";
import { import {
_encodePayGelatoProvider _encodePayGelatoProvider
@ -41,20 +41,21 @@ import {
import {_getGelatoProviderFees} from "../../functions/gelato/FGelato.sol"; import {_getGelatoProviderFees} from "../../functions/gelato/FGelato.sol";
import { import {
_getFlashLoanRoute, _getFlashLoanRoute,
_getGasCost, _getGasCostMakerToMaker,
_getBorrowAmountWithDelta _getGasCostMakerToCompound,
_getRealisedDebt
} from "../../functions/gelato/FGelatoDebtBridge.sol"; } from "../../functions/gelato/FGelatoDebtBridge.sol";
contract ConnectGelatoDataForFullRefinance is ConnectorInterface { contract ConnectGelatoDataFullRefinanceMaker is ConnectorInterface {
using GelatoBytes for bytes; using GelatoBytes for bytes;
// solhint-disable-next-line const-name-snakecase // solhint-disable const-name-snakecase
string public constant override name = "ConnectGelatoData-v1.0"; string
public constant
override name = "ConnectGelatoDataFullRefinanceMaker-v1.0";
uint256 internal immutable _id; uint256 internal immutable _id;
address internal immutable _connectGelatoProviderPayment; address internal immutable _connectGelatoProviderPayment;
uint256 public constant GAS_COST = 1850000;
constructor(uint256 id, address connectGelatoProviderPayment) { constructor(uint256 id, address connectGelatoProviderPayment) {
_id = id; _id = id;
_connectGelatoProviderPayment = connectGelatoProviderPayment; _connectGelatoProviderPayment = connectGelatoProviderPayment;
@ -74,21 +75,18 @@ contract ConnectGelatoDataForFullRefinance is ConnectorInterface {
/// @dev payable to be compatible in conjunction with DSA.cast payable target /// @dev payable to be compatible in conjunction with DSA.cast payable target
/// @param _vaultAId Id of the unsafe vault of the client of Vault A Collateral. /// @param _vaultAId Id of the unsafe vault of the client of Vault A Collateral.
/// @param _vaultBId Id of the vault B Collateral of the client. /// @param _vaultBId Id of the vault B Collateral of the client.
/// @param _token vault's col token address . /// @param _colToken vault's col token address .
/// @param _colType colType of the new vault. example : ETH-B, ETH-A. /// @param _colType colType of the new vault. example : ETH-B, ETH-A.
function getDataAndCastForFromMakerToMaker( function getDataAndCastMakerToMaker(
uint256 _vaultAId, uint256 _vaultAId,
uint256 _vaultBId, uint256 _vaultBId,
address _token, address _colToken,
string calldata _colType string calldata _colType
) external payable { ) external payable {
( (address[] memory targets, bytes[] memory datas) = _dataMakerToMaker(
address[] memory targets,
bytes[] memory datas
) = _execPayloadForFullRefinanceFromMakerToMaker(
_vaultAId, _vaultAId,
_vaultBId, _vaultBId,
_token, _colToken,
_colType _colType
); );
@ -98,15 +96,15 @@ contract ConnectGelatoDataForFullRefinance is ConnectorInterface {
/// @notice Entry Point for DSA.cast DebtBridge from Maker to Compound /// @notice Entry Point for DSA.cast DebtBridge from Maker to Compound
/// @dev payable to be compatible in conjunction with DSA.cast payable target /// @dev payable to be compatible in conjunction with DSA.cast payable target
/// @param _vaultId Id of the unsafe vault of the client. /// @param _vaultId Id of the unsafe vault of the client.
/// @param _token vault's col token address . /// @param _colToken vault's col token address .
function getDataAndCastForFromMakerToCompound( function getDataAndCastMakerToCompound(uint256 _vaultId, address _colToken)
uint256 _vaultId, external
address _token payable
) external payable { {
( (address[] memory targets, bytes[] memory datas) = _dataMakerToCompound(
address[] memory targets, _vaultId,
bytes[] memory datas _colToken
) = _execPayloadForFullRefinanceFromMakerToCompound(_vaultId, _token); );
_cast(targets, datas); _cast(targets, datas);
} }
@ -123,45 +121,45 @@ contract ConnectGelatoDataForFullRefinance is ConnectorInterface {
(bool success, bytes memory returndata) = address(this).delegatecall( (bool success, bytes memory returndata) = address(this).delegatecall(
castData castData
); );
if (!success) if (!success) {
returndata.revertWithError( returndata.revertWithError(
"ConnectGelatoDataForFullRefinance._cast:" "ConnectGelatoDataFullRefinanceMaker._cast:"
); );
}
} }
/* solhint-disable function-max-lines */ /* solhint-disable function-max-lines */
function _execPayloadForFullRefinanceFromMakerToMaker( function _dataMakerToMaker(
uint256 _vaultAId, uint256 _vaultAId,
uint256 _vaultBId, uint256 _vaultBId,
address _token, address _colToken,
string calldata _colType string calldata _colType
) internal view returns (address[] memory targets, bytes[] memory datas) { ) internal view returns (address[] memory targets, bytes[] memory datas) {
targets = new address[](1); targets = new address[](1);
targets[0] = INSTA_POOL_V2; targets[0] = INSTA_POOL_V2;
uint256 wDaiDebtToMove = _getMakerVaultDebt(_vaultAId); uint256 wDaiToBorrow = _getRealisedDebt(_getMakerVaultDebt(_vaultAId));
uint256 wDaiToBorrow = _getBorrowAmountWithDelta(wDaiDebtToMove);
uint256 wColToWithdrawFromMaker = _getMakerVaultCollateralBalance( uint256 wColToWithdrawFromMaker = _getMakerVaultCollateralBalance(
_vaultAId _vaultAId
); );
uint256 route = _getFlashLoanRoute(DAI, wDaiDebtToMove); uint256 route = _getFlashLoanRoute(DAI, wDaiToBorrow);
uint256 gasCost = _getGasCost(route); uint256 gasCost = _getGasCostMakerToMaker(_vaultBId == 0, route);
uint256 gasFeesPaidFromCol = _getGelatoProviderFees(gasCost); uint256 gasFeesPaidFromCol = _getGelatoProviderFees(gasCost);
(address[] memory _targets, bytes[] memory _datas) = _vaultBId == 0 (address[] memory _targets, bytes[] memory _datas) = _vaultBId == 0
? _spellsDebtBridgeWithOpenVaultAction( ? _spellsMakerToNewMakerVault(
_vaultAId, _vaultAId,
_token, _colToken,
_colType, _colType,
wDaiToBorrow, wDaiToBorrow,
wColToWithdrawFromMaker, wColToWithdrawFromMaker,
gasFeesPaidFromCol gasFeesPaidFromCol
) )
: _spellsDebtBridge( : _spellsMakerToMaker(
_vaultAId, _vaultAId,
_vaultBId, _vaultBId,
_token, _colToken,
wDaiToBorrow, wDaiToBorrow,
wColToWithdrawFromMaker, wColToWithdrawFromMaker,
gasFeesPaidFromCol gasFeesPaidFromCol
@ -177,57 +175,9 @@ contract ConnectGelatoDataForFullRefinance is ConnectorInterface {
); );
} }
function _execPayloadForFullRefinanceFromMakerToCompound( function _spellsMakerToNewMakerVault(
uint256 _vaultId,
address _token
) internal view returns (address[] memory targets, bytes[] memory datas) {
targets = new address[](1);
targets[0] = INSTA_POOL_V2;
uint256 wDaiDebtToMove = _getMakerVaultDebt(_vaultId);
uint256 wColToWithdrawFromMaker = _getMakerVaultCollateralBalance(
_vaultId
);
uint256 route = _getFlashLoanRoute(DAI, wDaiDebtToMove);
uint256 gasCost = _getGasCost(route);
uint256 gasFeesPaidFromCol = _getGelatoProviderFees(gasCost);
uint256 wDaiToBorrow = _getBorrowAmountWithDelta(wDaiDebtToMove);
address[] memory _targets = new address[](6);
_targets[0] = CONNECT_MAKER; // payback
_targets[1] = CONNECT_MAKER; // withdraw
_targets[2] = CONNECT_COMPOUND; // deposit
_targets[3] = CONNECT_COMPOUND; // borrow
_targets[4] = _connectGelatoProviderPayment; // payProvider
_targets[5] = INSTA_POOL_V2; // flashPayback
bytes[] memory _datas = new bytes[](6);
_datas[0] = _encodePaybackMakerVault(_vaultId, uint256(-1), 0, 600);
_datas[1] = _encodedWithdrawMakerVault(_vaultId, uint256(-1), 0, 0);
_datas[2] = _encodeDepositCompound(
_token,
sub(wColToWithdrawFromMaker, gasFeesPaidFromCol),
0,
0
);
_datas[3] = _encodeBorrowCompound(DAI, 0, 600, 0);
_datas[4] = _encodePayGelatoProvider(_token, gasFeesPaidFromCol, 0, 0);
_datas[5] = _encodeFlashPayback(DAI, wDaiToBorrow, 0, 0);
datas = new bytes[](1);
datas[0] = abi.encodeWithSelector(
IConnectInstaPoolV2.flashBorrowAndCast.selector,
DAI,
wDaiToBorrow,
route,
abi.encode(_targets, _datas)
);
}
function _spellsDebtBridgeWithOpenVaultAction(
uint256 _vaultAId, uint256 _vaultAId,
address _token, address _colToken,
string calldata _colType, string calldata _colType,
uint256 _wDaiToBorrow, uint256 _wDaiToBorrow,
uint256 _wColToWithdrawFromMaker, uint256 _wColToWithdrawFromMaker,
@ -236,7 +186,7 @@ contract ConnectGelatoDataForFullRefinance is ConnectorInterface {
targets = new address[](7); targets = new address[](7);
targets[0] = CONNECT_MAKER; // payback targets[0] = CONNECT_MAKER; // payback
targets[1] = CONNECT_MAKER; // withdraw targets[1] = CONNECT_MAKER; // withdraw
targets[2] = CONNECT_MAKER; // open ETH-B vault targets[2] = CONNECT_MAKER; // open new B vault
targets[3] = CONNECT_MAKER; // deposit targets[3] = CONNECT_MAKER; // deposit
targets[4] = CONNECT_MAKER; // borrow targets[4] = CONNECT_MAKER; // borrow
targets[5] = _connectGelatoProviderPayment; // payProvider targets[5] = _connectGelatoProviderPayment; // payProvider
@ -252,15 +202,20 @@ contract ConnectGelatoDataForFullRefinance is ConnectorInterface {
0, 0,
0 0
); );
datas[4] = _encodeBorrowDaiMakerVault(0, 0, 600, 0); datas[4] = _encodeBorrowMakerVault(0, 0, 600, 0);
datas[5] = _encodePayGelatoProvider(_token, _gasFeesPaidFromCol, 0, 0); datas[5] = _encodePayGelatoProvider(
_colToken,
_gasFeesPaidFromCol,
0,
0
);
datas[6] = _encodeFlashPayback(DAI, _wDaiToBorrow, 0, 0); datas[6] = _encodeFlashPayback(DAI, _wDaiToBorrow, 0, 0);
} }
function _spellsDebtBridge( function _spellsMakerToMaker(
uint256 _vaultAId, uint256 _vaultAId,
uint256 _vaultBId, uint256 _vaultBId,
address _token, address _colToken,
uint256 _wDaiToBorrow, uint256 _wDaiToBorrow,
uint256 _wColToWithdrawFromMaker, uint256 _wColToWithdrawFromMaker,
uint256 _gasFeesPaidFromCol uint256 _gasFeesPaidFromCol
@ -282,10 +237,67 @@ contract ConnectGelatoDataForFullRefinance is ConnectorInterface {
0, 0,
0 0
); );
datas[3] = _encodeBorrowDaiMakerVault(_vaultBId, 0, 600, 0); datas[3] = _encodeBorrowMakerVault(_vaultBId, 0, 600, 0);
datas[4] = _encodePayGelatoProvider(_token, _gasFeesPaidFromCol, 0, 0); datas[4] = _encodePayGelatoProvider(
_colToken,
_gasFeesPaidFromCol,
0,
0
);
datas[5] = _encodeFlashPayback(DAI, _wDaiToBorrow, 0, 0); datas[5] = _encodeFlashPayback(DAI, _wDaiToBorrow, 0, 0);
} }
function _dataMakerToCompound(uint256 _vaultId, address _colToken)
internal
view
returns (address[] memory targets, bytes[] memory datas)
{
targets = new address[](1);
targets[0] = INSTA_POOL_V2;
uint256 wDaiToBorrow = _getRealisedDebt(_getMakerVaultDebt(_vaultId));
uint256 wColToWithdrawFromMaker = _getMakerVaultCollateralBalance(
_vaultId
);
uint256 route = _getFlashLoanRoute(DAI, wDaiToBorrow);
uint256 gasCost = _getGasCostMakerToCompound(route);
uint256 gasFeesPaidFromCol = _getGelatoProviderFees(gasCost);
address[] memory _targets = new address[](6);
_targets[0] = CONNECT_MAKER; // payback
_targets[1] = CONNECT_MAKER; // withdraw
_targets[2] = CONNECT_COMPOUND; // deposit
_targets[3] = CONNECT_COMPOUND; // borrow
_targets[4] = _connectGelatoProviderPayment; // payProvider
_targets[5] = INSTA_POOL_V2; // flashPayback
bytes[] memory _datas = new bytes[](6);
_datas[0] = _encodePaybackMakerVault(_vaultId, uint256(-1), 0, 600);
_datas[1] = _encodedWithdrawMakerVault(_vaultId, uint256(-1), 0, 0);
_datas[2] = _encodeDepositCompound(
_colToken,
sub(wColToWithdrawFromMaker, gasFeesPaidFromCol),
0,
0
);
_datas[3] = _encodeBorrowCompound(DAI, 0, 600, 0);
_datas[4] = _encodePayGelatoProvider(
_colToken,
gasFeesPaidFromCol,
0,
0
);
_datas[5] = _encodeFlashPayback(DAI, wDaiToBorrow, 0, 0);
datas = new bytes[](1);
datas[0] = abi.encodeWithSelector(
IConnectInstaPoolV2.flashBorrowAndCast.selector,
DAI,
wDaiToBorrow,
route,
abi.encode(_targets, _datas)
);
}
/* solhint-enable function-max-lines */ /* solhint-enable function-max-lines */
} }

View File

@ -29,7 +29,7 @@ import {
_encodedWithdrawMakerVault, _encodedWithdrawMakerVault,
_encodeOpenMakerVault, _encodeOpenMakerVault,
_encodedDepositMakerVault, _encodedDepositMakerVault,
_encodeBorrowDaiMakerVault _encodeBorrowMakerVault
} from "../../functions/InstaDapp/connectors/FConnectMaker.sol"; } from "../../functions/InstaDapp/connectors/FConnectMaker.sol";
import { import {
_encodePayGelatoProvider _encodePayGelatoProvider
@ -44,7 +44,7 @@ import {
_wCalcDebtToRepay _wCalcDebtToRepay
} from "../../functions/gelato/FGelatoDebtBridge.sol"; } from "../../functions/gelato/FGelatoDebtBridge.sol";
contract ConnectGelatoDataForPartialRefinance is ConnectorInterface { contract ConnectGelatoDataPartialRefinanceMaker is ConnectorInterface {
using GelatoBytes for bytes; using GelatoBytes for bytes;
// vaultId: Id of the unsafe vault of the client. // vaultId: Id of the unsafe vault of the client.
@ -57,15 +57,18 @@ contract ConnectGelatoDataForPartialRefinance is ConnectorInterface {
// method e.g. the function selector of MakerOracle's read function. // method e.g. the function selector of MakerOracle's read function.
struct PartialDebtBridgePayload { struct PartialDebtBridgePayload {
uint256 vaultId; uint256 vaultId;
address token; address colToken;
string colType;
uint256 wMinColRatioMaker; uint256 wMinColRatioMaker;
uint256 wMinColRatioB; uint256 wMinColRatioB;
address priceOracle; address priceOracle;
bytes oraclePayload; bytes oraclePayload;
} }
// solhint-disable-next-line const-name-snakecase // solhint-disable const-name-snakecase
string public constant override name = "ConnectGelatoData-v1.0"; string
public constant
override name = "ConnectGelatoDataPartialRefinanceMaker-v1.0";
uint256 internal immutable _id; uint256 internal immutable _id;
address internal immutable _connectGelatoProviderPayment; address internal immutable _connectGelatoProviderPayment;
@ -89,15 +92,12 @@ contract ConnectGelatoDataForPartialRefinance is ConnectorInterface {
/// @notice Entry Point for DSA.cast DebtBridge from e.g ETH-A to ETH-B /// @notice Entry Point for DSA.cast DebtBridge from e.g ETH-A to ETH-B
/// @dev payable to be compatible in conjunction with DSA.cast payable target /// @dev payable to be compatible in conjunction with DSA.cast payable target
/// @param _payload See PartialDebtBridgePayload struct /// @param _payload See PartialDebtBridgePayload struct
/// @param _colType colType of the new vault. example : ETH-B, ETH-A. function getDataAndCastMakerToMaker(
function getDataAndCastForFromMakerToMaker( PartialDebtBridgePayload calldata _payload
PartialDebtBridgePayload calldata _payload,
string calldata _colType
) external payable { ) external payable {
( (address[] memory targets, bytes[] memory datas) = _dataMakerToMaker(
address[] memory targets, _payload
bytes[] memory datas );
) = _execPayloadForPartialRefinanceFromMakerToMaker(_payload, _colType);
_cast(targets, datas); _cast(targets, datas);
} }
@ -105,13 +105,12 @@ contract ConnectGelatoDataForPartialRefinance is ConnectorInterface {
/// @notice Entry Point for DSA.cast DebtBridge from Maker to Compound /// @notice Entry Point for DSA.cast DebtBridge from Maker to Compound
/// @dev payable to be compatible in conjunction with DSA.cast payable target /// @dev payable to be compatible in conjunction with DSA.cast payable target
/// @param _payload See PartialDebtBridgePayload struct /// @param _payload See PartialDebtBridgePayload struct
function getDataAndCastForFromMakerToCompound( function getDataAndCastMakerToCompound(
PartialDebtBridgePayload calldata _payload PartialDebtBridgePayload calldata _payload
) external payable { ) external payable {
( (address[] memory targets, bytes[] memory datas) = _dataMakerToCompound(
address[] memory targets, _payload
bytes[] memory datas );
) = _execPayloadForPartialRefinanceFromMakerToCompound(_payload);
_cast(targets, datas); _cast(targets, datas);
} }
@ -130,16 +129,17 @@ contract ConnectGelatoDataForPartialRefinance is ConnectorInterface {
); );
if (!success) if (!success)
returndata.revertWithError( returndata.revertWithError(
"ConnectGelatoDataForPartialRefinance._cast:" "ConnectGelatoDataPartialRefinanceMaker._cast:"
); );
} }
/* solhint-disable function-max-lines */ /* solhint-disable function-max-lines */
function _execPayloadForPartialRefinanceFromMakerToMaker( function _dataMakerToMaker(PartialDebtBridgePayload calldata _payload)
PartialDebtBridgePayload calldata _payload, internal
string calldata _colType view
) internal view returns (address[] memory targets, bytes[] memory datas) { returns (address[] memory targets, bytes[] memory datas)
{
targets = new address[](1); targets = new address[](1);
targets[0] = INSTA_POOL_V2; targets[0] = INSTA_POOL_V2;
@ -177,16 +177,16 @@ contract ConnectGelatoDataForPartialRefinance is ConnectorInterface {
0, 0,
0 0
); );
_datas[2] = _encodeOpenMakerVault(_colType); _datas[2] = _encodeOpenMakerVault(_payload.colType);
_datas[3] = _encodedDepositMakerVault( _datas[3] = _encodedDepositMakerVault(
0, 0,
sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), sub(wColToWithdrawFromMaker, gasFeesPaidFromCol),
0, 0,
0 0
); );
_datas[4] = _encodeBorrowDaiMakerVault(0, wDaiDebtToMove, 0, 0); _datas[4] = _encodeBorrowMakerVault(0, wDaiDebtToMove, 0, 0);
_datas[5] = _encodePayGelatoProvider( _datas[5] = _encodePayGelatoProvider(
_payload.token, _payload.colToken,
gasFeesPaidFromCol, gasFeesPaidFromCol,
0, 0,
0 0
@ -203,9 +203,11 @@ contract ConnectGelatoDataForPartialRefinance is ConnectorInterface {
); );
} }
function _execPayloadForPartialRefinanceFromMakerToCompound( function _dataMakerToCompound(PartialDebtBridgePayload calldata _payload)
PartialDebtBridgePayload calldata _payload internal
) internal view returns (address[] memory targets, bytes[] memory datas) { view
returns (address[] memory targets, bytes[] memory datas)
{
targets = new address[](1); targets = new address[](1);
targets[0] = INSTA_POOL_V2; targets[0] = INSTA_POOL_V2;
@ -243,14 +245,14 @@ contract ConnectGelatoDataForPartialRefinance is ConnectorInterface {
0 0
); );
_datas[2] = _encodeDepositCompound( _datas[2] = _encodeDepositCompound(
_payload.token, _payload.colToken,
sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), sub(wColToWithdrawFromMaker, gasFeesPaidFromCol),
0, 0,
0 0
); );
_datas[3] = _encodeBorrowCompound(DAI, wDaiDebtToMove, 0, 0); _datas[3] = _encodeBorrowCompound(DAI, wDaiDebtToMove, 0, 0);
_datas[4] = _encodePayGelatoProvider( _datas[4] = _encodePayGelatoProvider(
_payload.token, _payload.colToken,
gasFeesPaidFromCol, gasFeesPaidFromCol,
0, 0,
0 0

View File

@ -15,7 +15,8 @@ import {
} from "../../../functions/dapps/FMaker.sol"; } from "../../../functions/dapps/FMaker.sol";
import { import {
_getFlashLoanRoute, _getFlashLoanRoute,
_getGasCost _getGasCostMakerToMaker,
_getRealisedDebt
} from "../../../functions/gelato/FGelatoDebtBridge.sol"; } from "../../../functions/gelato/FGelatoDebtBridge.sol";
import {_getGelatoProviderFees} from "../../../functions/gelato/FGelato.sol"; import {_getGelatoProviderFees} from "../../../functions/gelato/FGelato.sol";
import {DAI} from "../../../constants/CInstaDapp.sol"; import {DAI} from "../../../constants/CInstaDapp.sol";
@ -73,10 +74,16 @@ contract ConditionDebtBridgeIsAffordable is GelatoConditionsStandard {
_vaultId _vaultId
); );
uint256 gasFeesPaidFromCol = _getGelatoProviderFees( uint256 gasFeesPaidFromCol = _getGelatoProviderFees(
_getGasCost(_getFlashLoanRoute(DAI, _getMakerVaultDebt(_vaultId))) _getGasCostMakerToMaker(
true,
_getFlashLoanRoute(
DAI,
_getRealisedDebt(_getMakerVaultDebt(_vaultId))
)
)
); );
if (wdiv(gasFeesPaidFromCol, wColToWithdrawFromMaker) >= _ratioLimit) if (wdiv(gasFeesPaidFromCol, wColToWithdrawFromMaker) >= _ratioLimit)
return "DebtRefinanceTooExpensive"; return "DebtBridgeNotAffordable";
return OK; return OK;
} }
} }

View File

@ -6,7 +6,7 @@ import {
} from "../../../interfaces/InstaDapp/connectors/IConnectCompound.sol"; } from "../../../interfaces/InstaDapp/connectors/IConnectCompound.sol";
function _encodeDepositCompound( function _encodeDepositCompound(
address _token, address _colToken,
uint256 _amt, uint256 _amt,
uint256 _getId, uint256 _getId,
uint256 _setId uint256 _setId
@ -14,7 +14,7 @@ function _encodeDepositCompound(
return return
abi.encodeWithSelector( abi.encodeWithSelector(
IConnectCompound.deposit.selector, IConnectCompound.deposit.selector,
_token, _colToken,
_amt, _amt,
_getId, _getId,
_setId _setId
@ -22,7 +22,7 @@ function _encodeDepositCompound(
} }
function _encodeBorrowCompound( function _encodeBorrowCompound(
address _token, address _colToken,
uint256 _amt, uint256 _amt,
uint256 _getId, uint256 _getId,
uint256 _setId uint256 _setId
@ -30,7 +30,7 @@ function _encodeBorrowCompound(
return return
abi.encodeWithSelector( abi.encodeWithSelector(
IConnectCompound.borrow.selector, IConnectCompound.borrow.selector,
_token, _colToken,
_amt, _amt,
_getId, _getId,
_setId _setId

View File

@ -6,7 +6,7 @@ import {
} from "../../../interfaces/InstaDapp/connectors/IConnectGelatoProviderPayment.sol"; } from "../../../interfaces/InstaDapp/connectors/IConnectGelatoProviderPayment.sol";
function _encodePayGelatoProvider( function _encodePayGelatoProvider(
address _token, address _colToken,
uint256 _amt, uint256 _amt,
uint256 _getId, uint256 _getId,
uint256 _setId uint256 _setId
@ -14,7 +14,7 @@ function _encodePayGelatoProvider(
return return
abi.encodeWithSelector( abi.encodeWithSelector(
IConnectGelatoProviderPayment.payProvider.selector, IConnectGelatoProviderPayment.payProvider.selector,
_token, _colToken,
_amt, _amt,
_getId, _getId,
_setId _setId

View File

@ -12,7 +12,7 @@ function _encodeOpenMakerVault(string memory _colType)
return abi.encodeWithSelector(IConnectMaker.open.selector, _colType); return abi.encodeWithSelector(IConnectMaker.open.selector, _colType);
} }
function _encodeBorrowDaiMakerVault( function _encodeBorrowMakerVault(
uint256 _vaultId, uint256 _vaultId,
uint256 _amt, uint256 _amt,
uint256 _getId, uint256 _getId,

View File

@ -6,7 +6,7 @@ import {
} from "../../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol"; } from "../../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol";
function _encodeFlashPayback( function _encodeFlashPayback(
address _token, address _colToken,
uint256 _amt, uint256 _amt,
uint256 _getId, uint256 _getId,
uint256 _setId uint256 _setId
@ -14,7 +14,7 @@ function _encodeFlashPayback(
return return
abi.encodeWithSelector( abi.encodeWithSelector(
IConnectInstaPoolV2.flashPayback.selector, IConnectInstaPoolV2.flashPayback.selector,
_token, _colToken,
_amt, _amt,
_getId, _getId,
_setId _setId

View File

@ -2,8 +2,11 @@
pragma solidity 0.7.4; pragma solidity 0.7.4;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import {sub, wmul, wdiv} from "../../vendor/DSMath.sol"; import {add, sub, wmul, wdiv} from "../../vendor/DSMath.sol";
import {INSTA_POOL_RESOLVER} from "../../constants/CInstaDapp.sol"; import {
INSTA_POOL_RESOLVER,
ROUTE_1_3_TOLERANCE
} from "../../constants/CInstaDapp.sol";
import {GAS_COSTS_FOR_FULL_REFINANCE} from "../../constants/CDebtBridge.sol"; import {GAS_COSTS_FOR_FULL_REFINANCE} from "../../constants/CDebtBridge.sol";
import { import {
IInstaPoolResolver IInstaPoolResolver
@ -54,28 +57,36 @@ function _wCalcDebtToRepay(
); );
} }
function _getFlashLoanRoute(address _tokenA, uint256 _wTokenADebtToMove) function _getFlashLoanRoute(address _colTokenA, uint256 _wTokenADebtToMove)
view view
returns (uint256) returns (uint256)
{ {
IInstaPoolResolver.RouteData memory rData = IInstaPoolResolver( IInstaPoolResolver.RouteData memory rData = IInstaPoolResolver(
INSTA_POOL_RESOLVER INSTA_POOL_RESOLVER
) )
.getTokenLimit(_tokenA); .getTokenLimit(_colTokenA);
if (rData.dydx > _wTokenADebtToMove) return 0; if (rData.dydx > _wTokenADebtToMove) return 0;
if (rData.maker > _wTokenADebtToMove) return 1; if (rData.maker > _wTokenADebtToMove) return 1;
if (rData.compound > _wTokenADebtToMove) return 2; if (rData.compound > _wTokenADebtToMove) return 2;
if (rData.aave > _wTokenADebtToMove) return 3; if (rData.aave > _wTokenADebtToMove) return 3;
revert( revert("FGelatoDebtBridge._getFlashLoanRoute: illiquid");
"GelateDebtBridge._getRoute: All route have insufficient liquidties."
);
} }
function _getGasCost(uint256 _route) pure returns (uint256) { function _getGasCostMakerToMaker(bool _newVault, uint256 _route)
pure
returns (uint256)
{
return
_newVault
? add(GAS_COSTS_FOR_FULL_REFINANCE()[_route], 0)
: GAS_COSTS_FOR_FULL_REFINANCE()[_route];
}
function _getGasCostMakerToCompound(uint256 _route) pure returns (uint256) {
return GAS_COSTS_FOR_FULL_REFINANCE()[_route]; return GAS_COSTS_FOR_FULL_REFINANCE()[_route];
} }
function _getBorrowAmountWithDelta(uint256 _DebtToMove) pure returns (uint256) { function _getRealisedDebt(uint256 _debtToMove) pure returns (uint256) {
return wmul(_DebtToMove, 1005e15); return wmul(_debtToMove, ROUTE_1_3_TOLERANCE);
} }

View File

@ -7,7 +7,7 @@ interface IConnectGelatoProviderPayment is ConnectorInterface {
function setProvider(address _provider) external; function setProvider(address _provider) external;
function payProvider( function payProvider(
address _token, address _colToken,
uint256 _amt, uint256 _amt,
uint256 _getId, uint256 _getId,
uint256 _setId uint256 _setId

View File

@ -8,7 +8,7 @@ const InstaConnector = require("../../pre-compiles/InstaConnectors.json");
module.exports = async (hre) => { module.exports = async (hre) => {
if (hre.network.name === "mainnet") { if (hre.network.name === "mainnet") {
console.log( console.log(
"Deploying ConnectGelatoDataForFullRefinance to mainnet. Hit ctrl + c to abort" "Deploying ConnectGelatoDataFullRefinanceMaker to mainnet. Hit ctrl + c to abort"
); );
await sleep(10000); await sleep(10000);
} }
@ -24,9 +24,9 @@ module.exports = async (hre) => {
const connectorLength = await instaConnectors.connectorLength(); const connectorLength = await instaConnectors.connectorLength();
const connectorId = connectorLength.add(1); const connectorId = connectorLength.add(1);
// the following will only deploy "ConnectGelatoDataForFullRefinance" // the following will only deploy "ConnectGelatoDataFullRefinanceMaker"
// if the contract was never deployed or if the code changed since last deployment // if the contract was never deployed or if the code changed since last deployment
await deploy("ConnectGelatoDataForFullRefinance", { await deploy("ConnectGelatoDataFullRefinanceMaker", {
from: deployer, from: deployer,
args: [ args: [
connectorId, connectorId,
@ -55,7 +55,8 @@ module.exports = async (hre) => {
await instaConnectors await instaConnectors
.connect(instaMaster) .connect(instaMaster)
.enable( .enable(
(await ethers.getContract("ConnectGelatoDataForFullRefinance")).address (await ethers.getContract("ConnectGelatoDataFullRefinanceMaker"))
.address
); );
await hre.network.provider.request({ await hre.network.provider.request({
@ -66,4 +67,4 @@ module.exports = async (hre) => {
}; };
module.exports.dependencies = ["ConnectGelatoProviderPayment"]; module.exports.dependencies = ["ConnectGelatoProviderPayment"];
module.exports.tags = ["ConnectGelatoDataForFullRefinance"]; module.exports.tags = ["ConnectGelatoDataFullRefinanceMaker"];

View File

@ -8,7 +8,7 @@ const InstaConnector = require("../../pre-compiles/InstaConnectors.json");
module.exports = async (hre) => { module.exports = async (hre) => {
if (hre.network.name === "mainnet") { if (hre.network.name === "mainnet") {
console.log( console.log(
"Deploying ConnectGelatoDataForPartialRefinance to mainnet. Hit ctrl + c to abort" "Deploying ConnectGelatoDataPartialRefinanceMaker to mainnet. Hit ctrl + c to abort"
); );
await sleep(10000); await sleep(10000);
} }
@ -24,9 +24,9 @@ module.exports = async (hre) => {
const connectorLength = await instaConnectors.connectorLength(); const connectorLength = await instaConnectors.connectorLength();
const connectorId = connectorLength.add(1); const connectorId = connectorLength.add(1);
// the following will only deploy "ConnectGelatoDataForPartialRefinance" // the following will only deploy "ConnectGelatoDataPartialRefinanceMaker"
// if the contract was never deployed or if the code changed since last deployment // if the contract was never deployed or if the code changed since last deployment
await deploy("ConnectGelatoDataForPartialRefinance", { await deploy("ConnectGelatoDataPartialRefinanceMaker", {
from: deployer, from: deployer,
args: [ args: [
connectorId, connectorId,
@ -55,7 +55,7 @@ module.exports = async (hre) => {
await instaConnectors await instaConnectors
.connect(instaMaster) .connect(instaMaster)
.enable( .enable(
(await ethers.getContract("ConnectGelatoDataForPartialRefinance")) (await ethers.getContract("ConnectGelatoDataPartialRefinanceMaker"))
.address .address
); );
@ -69,5 +69,5 @@ module.exports = async (hre) => {
module.exports.skip = async (hre) => { module.exports.skip = async (hre) => {
return hre.network.name === "mainnet" ? true : false; return hre.network.name === "mainnet" ? true : false;
}; };
module.exports.tags = ["ConnectGelatoDataForPartialRefinance"]; module.exports.tags = ["ConnectGelatoDataPartialRefinanceMaker"];
module.exports.dependencies = ["ConnectGelatoProviderPayment"]; module.exports.dependencies = ["ConnectGelatoProviderPayment"];

View File

@ -21,7 +21,7 @@
"@nomiclabs/hardhat-waffle": "2.0.0", "@nomiclabs/hardhat-waffle": "2.0.0",
"chai": "4.2.0", "chai": "4.2.0",
"dotenv": "8.2.0", "dotenv": "8.2.0",
"eslint": "7.12.1", "eslint": "7.13.0",
"eslint-config-prettier": "6.15.0", "eslint-config-prettier": "6.15.0",
"ethereum-waffle": "3.2.0", "ethereum-waffle": "3.2.0",
"ethers": "5.0.19", "ethers": "5.0.19",
@ -32,7 +32,7 @@
"lint-staged": "10.5.1", "lint-staged": "10.5.1",
"prettier": "2.1.2", "prettier": "2.1.2",
"prettier-plugin-solidity": "1.0.0-alpha.59", "prettier-plugin-solidity": "1.0.0-alpha.59",
"solhint": "3.3.1", "solhint": "3.3.2",
"solhint-plugin-prettier": "0.0.5" "solhint-plugin-prettier": "0.0.5"
}, },
"dependencies": {}, "dependencies": {},

View File

@ -173,7 +173,7 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "max_tokens", "name": "max_colTokens",
"type": "uint256" "type": "uint256"
}, },
{ {
@ -275,7 +275,7 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "min_tokens_bought", "name": "min_colTokens_bought",
"type": "uint256" "type": "uint256"
}, },
{ {

View File

@ -103,8 +103,8 @@ async function getContracts() {
"ConnectGelatoProviderPayment" "ConnectGelatoProviderPayment"
); );
const makerResolver = await ethers.getContract("MakerResolver"); const makerResolver = await ethers.getContract("MakerResolver");
const connectGelatoDataForFullRefinance = await ethers.getContract( const connectGelatoDataFullRefinanceMaker = await ethers.getContract(
"ConnectGelatoDataForFullRefinance" "ConnectGelatoDataFullRefinanceMaker"
); );
return { return {
@ -112,7 +112,7 @@ async function getContracts() {
connectMaker, connectMaker,
connectInstaPool, connectInstaPool,
connectCompound, connectCompound,
connectGelatoDataForFullRefinance, connectGelatoDataFullRefinanceMaker,
instaIndex, instaIndex,
instaList, instaList,
instaMapping, instaMapping,

View File

@ -20,11 +20,12 @@ async function providerWhiteListTaskForMakerETHAToMakerETHB(
const spells = []; const spells = [];
const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({ const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({
addr: contracts.connectGelatoDataForFullRefinance.address, addr: contracts.connectGelatoDataFullRefinanceMaker.address,
data: await hre.run("abi-encode-withselector", { data: await hre.run("abi-encode-withselector", {
abi: (await deployments.getArtifact("ConnectGelatoDataForFullRefinance")) abi: (
.abi, await deployments.getArtifact("ConnectGelatoDataFullRefinanceMaker")
functionname: "getDataAndCastForFromMakerToMaker", ).abi,
functionname: "getDataAndCastMakerToMaker",
inputs: [vaultId, 0, constants.ETH, "ETH-B"], inputs: [vaultId, 0, constants.ETH, "ETH-B"],
}), }),
operation: GelatoCoreLib.Operation.Delegatecall, operation: GelatoCoreLib.Operation.Delegatecall,

View File

@ -21,11 +21,12 @@ async function providerWhiteListTaskForMakerETHAToMakerETHBWithVaultB(
const spells = []; const spells = [];
const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({ const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({
addr: contracts.connectGelatoDataForFullRefinance.address, addr: contracts.connectGelatoDataFullRefinanceMaker.address,
data: await hre.run("abi-encode-withselector", { data: await hre.run("abi-encode-withselector", {
abi: (await deployments.getArtifact("ConnectGelatoDataForFullRefinance")) abi: (
.abi, await deployments.getArtifact("ConnectGelatoDataFullRefinanceMaker")
functionname: "getDataAndCastForFromMakerToMaker", ).abi,
functionname: "getDataAndCastMakerToMaker",
inputs: [vaultAId, vaultBId, constants.ETH, "ETH-B"], inputs: [vaultAId, vaultBId, constants.ETH, "ETH-B"],
}), }),
operation: GelatoCoreLib.Operation.Delegatecall, operation: GelatoCoreLib.Operation.Delegatecall,

View File

@ -20,11 +20,12 @@ async function providerWhiteListTaskForMakerToCompound(
const spells = []; const spells = [];
const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({ const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({
addr: contracts.connectGelatoDataForFullRefinance.address, addr: contracts.connectGelatoDataFullRefinanceMaker.address,
data: await hre.run("abi-encode-withselector", { data: await hre.run("abi-encode-withselector", {
abi: (await deployments.getArtifact("ConnectGelatoDataForFullRefinance")) abi: (
.abi, await deployments.getArtifact("ConnectGelatoDataFullRefinanceMaker")
functionname: "getDataAndCastForFromMakerToCompound", ).abi,
functionname: "getDataAndCastMakerToCompound",
inputs: [vaultId, constants.ETH], inputs: [vaultId, constants.ETH],
}), }),
operation: GelatoCoreLib.Operation.Delegatecall, operation: GelatoCoreLib.Operation.Delegatecall,

View File

@ -133,7 +133,7 @@ describe("ConditionDebtBridgeIsAffordable Unit Test", function () {
); );
}); });
it("#1: ok should return DebtRefinanceTooExpensive when the gas fees exceed a define amount", async function () { it("#1: ok should return DebtBridgeNotAffordable when the gas fees exceed a define amount", async function () {
const conditionData = await conditionDebtBridgeIsAffordable.getConditionData( const conditionData = await conditionDebtBridgeIsAffordable.getConditionData(
cdpId, cdpId,
ethers.utils.parseUnits("5", 15) ethers.utils.parseUnits("5", 15)
@ -141,7 +141,7 @@ describe("ConditionDebtBridgeIsAffordable Unit Test", function () {
expect( expect(
await conditionDebtBridgeIsAffordable.ok(0, conditionData, 0) await conditionDebtBridgeIsAffordable.ok(0, conditionData, 0)
).to.be.equal("DebtRefinanceTooExpensive"); ).to.be.equal("DebtBridgeNotAffordable");
}); });
it("#2: ok should return OK when the gas fees not exceed a define amount", async function () { it("#2: ok should return OK when the gas fees not exceed a define amount", async function () {

View File

@ -683,6 +683,11 @@
resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.8.1.tgz#1b606578af86b9ad10755409804a6ba83f9ce8a4" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.8.1.tgz#1b606578af86b9ad10755409804a6ba83f9ce8a4"
integrity sha512-DF7H6T8I4lo2IZOE2NZwt3631T8j1gjpQLjmvY2xBNK50c4ltslR4XPKwT6RkeSd4+xCAK0GHC/k7sbRDBE4Yw== integrity sha512-DF7H6T8I4lo2IZOE2NZwt3631T8j1gjpQLjmvY2xBNK50c4ltslR4XPKwT6RkeSd4+xCAK0GHC/k7sbRDBE4Yw==
"@solidity-parser/parser@^0.8.2":
version "0.8.2"
resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.8.2.tgz#a6a5e93ac8dca6884a99a532f133beba59b87b69"
integrity sha512-8LySx3qrNXPgB5JiULfG10O3V7QTxI/TLzSw5hFQhXWSkVxZBAv4rZQ0sYgLEbc8g3L2lmnujj1hKul38Eu5NQ==
"@szmarczak/http-timer@^1.1.2": "@szmarczak/http-timer@^1.1.2":
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
@ -2919,10 +2924,10 @@ eslint-visitor-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
eslint@7.12.1: eslint@7.13.0:
version "7.12.1" version "7.13.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.12.1.tgz#bd9a81fa67a6cfd51656cdb88812ce49ccec5801" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.13.0.tgz#7f180126c0dcdef327bfb54b211d7802decc08da"
integrity sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg== integrity sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==
dependencies: dependencies:
"@babel/code-frame" "^7.0.0" "@babel/code-frame" "^7.0.0"
"@eslint/eslintrc" "^0.2.1" "@eslint/eslintrc" "^0.2.1"
@ -7296,12 +7301,12 @@ solhint-plugin-prettier@0.0.5:
dependencies: dependencies:
prettier-linter-helpers "^1.0.0" prettier-linter-helpers "^1.0.0"
solhint@3.3.1: solhint@3.3.2:
version "3.3.1" version "3.3.2"
resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.1.tgz#7aa02afb79ad2bcfa64885b1fe134e220949546f" resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.2.tgz#ebd7270bb50fd378b427d7a6fc9f2a7fd00216c0"
integrity sha512-JXAOLM2UQrLOtx4fKXzleq6CR0N7AlRfki+dFyvab93x4DoHeHQ4Ic2LMScT8V0AddXgbKtR8xdIIZKLh07dNg== integrity sha512-8tHCkIAk1axLLG6Qu2WIH3GgNABonj9eAWejJbov3o3ujkZQRNHeHU1cC4/Dmjsh3Om7UzFFeADUHu2i7ZJeiw==
dependencies: dependencies:
"@solidity-parser/parser" "^0.8.1" "@solidity-parser/parser" "^0.8.2"
ajv "^6.6.1" ajv "^6.6.1"
antlr4 "4.7.1" antlr4 "4.7.1"
ast-parents "0.0.1" ast-parents "0.0.1"