diff --git a/.prettierignore b/.prettierignore index da5fa0f..eb50ac5 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,4 +3,5 @@ artifacts cache assets coverage +contracts/constants contracts/vendor \ No newline at end of file diff --git a/.solhintignore b/.solhintignore index f0ab30b..11d5330 100644 --- a/.solhintignore +++ b/.solhintignore @@ -1,2 +1,3 @@ node_modules/ +contracts/constants contracts/vendor \ No newline at end of file diff --git a/README.md b/README.md index 6eda71f..49f4cff 100644 --- a/README.md +++ b/README.md @@ -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. -Based on the [debt bridge](https://docs.instadapp.io/usecases/debt-bridge/) documentation of Instadapp, we automated this process by adding two connectors `ConnectGelatoDebtBridge`, `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 `ConnectGelatoData`, `ConnectGelatoProviderPayment` and a Gelato condition contract. - `ConditionMakerVaultIsSafe.sol`: determine if a specific vault is on an unsafe position. -- `ConnectGelatoDebtBridge.sol`: generates the required data which will be assigned to the different inputs needed by `ConnectMaker` and `ConnectCompound` by using InstaMemory. Examples are the amount of DAI to pay back or the amount of Ether to withdraw from Maker. +- `ConnectGelatoData.sol`: generates the required data which will be assigned to the different inputs needed by `ConnectMaker` and `ConnectCompound` by using InstaMemory. Examples are the amount of DAI to pay back or the amount of Ether to withdraw from Maker. - `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. diff --git a/contracts/connectors/ConnectGelatoDebtBridge.sol b/contracts/connectors/ConnectGelatoDebtBridge.sol deleted file mode 100644 index 994b9fe..0000000 --- a/contracts/connectors/ConnectGelatoDebtBridge.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.7.4; -pragma experimental ABIEncoderV2; - -import {GelatoBytes} from "../lib/GelatoBytes.sol"; -import {IFlashLoan} from "../interfaces/IFlashLoan.sol"; -import {DSAInterface} from "../interfaces/DSAInterface.sol"; - -/* solhint-disable */ - -interface ConnectorInterface { - function connectorID() external view returns (uint256 _type, uint256 _id); - - function name() external view returns (string memory); -} - -abstract contract Helper is ConnectorInterface { - uint256 internal __id; - - /** - * @dev Connector Details - */ - function connectorID() - public - view - override - returns (uint256 _type, uint256 id) - { - (_type, id) = (1, __id); // Should put specific value. - } -} - -contract ConnectGelatoDebtBridge is Helper { - using GelatoBytes for bytes; - - // solhint-disable-next-line const-name-snakecase - string public constant override name = "GelatoDebtBridge-v1.0"; - address public immutable connectAddr; - - constructor(uint256 _id) { - __id = _id; - connectAddr = address(this); - } - - function computeRefinanceDataAndCast(address _target, bytes calldata _data) - public - payable - { - (bool success, bytes memory returndata) = _target.staticcall(_data); - if (!success) { - revert( - returndata.generateErrorString( - "ConnectGelatoDebtBridge.computeRefinanceDataAndCast._target:" - ) - ); - } - - (address target, bytes memory data) = abi.decode( - returndata, - (address, bytes) - ); - - address[] memory targets = new address[](1); - targets[0] = target; - bytes[] memory datas = new bytes[](1); - datas[0] = data; - - // Instapool V2 / FlashLoan call - bytes memory castData = abi.encodeWithSelector( - DSAInterface.cast.selector, - targets, - datas, - connectAddr - ); - - _cast(address(this), castData); - } - - function _cast(address _target, bytes memory _data) internal { - require(_target != address(0), "target-invalid"); - assembly { - let succeeded := delegatecall( - gas(), - _target, - add(_data, 0x20), - mload(_data), - 0, - 0 - ) - - switch iszero(succeeded) - case 1 { - // throw if delegatecall failed - let size := returndatasize() - returndatacopy(0x00, 0x00, size) - revert(0x00, size) - } - } - } -} diff --git a/contracts/constants/CGelato.sol b/contracts/constants/CGelato.sol new file mode 100644 index 0000000..46207a3 --- /dev/null +++ b/contracts/constants/CGelato.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import { + IGelatoGasPriceOracle +} from "../interfaces/gelato/IGelatoGasPriceOracle.sol"; + +IGelatoGasPriceOracle constant GELATO_GAS_PRICE_ORACLE = IGelatoGasPriceOracle( + 0x169E633A2D1E6c10dD91238Ba11c4A708dfEF37C +); diff --git a/contracts/constants/CInstaDapp.sol b/contracts/constants/CInstaDapp.sol new file mode 100644 index 0000000..b86fab7 --- /dev/null +++ b/contracts/constants/CInstaDapp.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +// InstaDapp +address constant INSTA_MEMORY = 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; + +// Connectors +address constant CONNECT_MAKER = 0xac02030d8a8F49eD04b2f52C394D3F901A10F8A9; +address constant CONNECT_COMPOUND = 0x07F81230d73a78f63F0c2A3403AD281b067d28F8; +address constant INSTA_POOL_V2 = 0x3150e5A805577366816A1ddc7330c6Ea17070c05; + +// Tokens +address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; +address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; diff --git a/contracts/contracts/connectors/ConnectGelatoData.sol b/contracts/contracts/connectors/ConnectGelatoData.sol new file mode 100644 index 0000000..25cefe9 --- /dev/null +++ b/contracts/contracts/connectors/ConnectGelatoData.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; +pragma experimental ABIEncoderV2; + +import {GelatoBytes} from "../../lib/GelatoBytes.sol"; +import { + AccountInterface, + ConnectorInterface +} from "../../interfaces/InstaDapp/IInstaDapp.sol"; +import { + IConnectInstaPoolV2 +} from "../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol"; + +contract ConnectGelatoData is ConnectorInterface { + using GelatoBytes for bytes; + + // solhint-disable-next-line const-name-snakecase + string public constant override name = "ConnectGelatoData-v1.0"; + uint256 internal immutable _id; + + constructor(uint256 id) { + _id = id; + } + + /// @dev Connector Details + function connectorID() + public + view + override + returns (uint256 _type, uint256 id) + { + (_type, id) = (1, _id); // Should put specific value. + } + + function getDataAndCast(address _target, bytes calldata _data) + public + payable + { + (bool success, bytes memory returndata) = _target.staticcall(_data); + if (!success) { + returndata.revertWithError( + "ConnectGelatoData.getDataAndCast._target:" + ); + } + + (address[] memory targets, bytes[] memory datas) = abi.decode( + returndata, + (address[], bytes[]) + ); + + // Instapool V2 / FlashLoan call + bytes memory castData = abi.encodeWithSelector( + AccountInterface.cast.selector, + targets, + datas, + msg.sender // msg.sender == GelatoCore + ); + + (success, returndata) = address(this).delegatecall(castData); + if (!success) + returndata.revertWithError("ConnectGelatoData.getDataAndCast:"); + } +} diff --git a/contracts/contracts/connectors/ConnectGelatoProviderPayment.sol b/contracts/contracts/connectors/ConnectGelatoProviderPayment.sol new file mode 100644 index 0000000..1cdbf6c --- /dev/null +++ b/contracts/contracts/connectors/ConnectGelatoProviderPayment.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import {ConnectorInterface} from "../../interfaces/InstaDapp/IInstaDapp.sol"; +import {Address} from "../../vendor/Address.sol"; +import {IERC20} from "../../interfaces/tokens/IERC20.sol"; +import {SafeERC20} from "../../vendor/SafeERC20.sol"; +import {getUint, setUint} from "../../functions/InstaDapp/FInstaDapp.sol"; +import {ETH} from "../../constants/CInstaDapp.sol"; + +/// @title ConnectGelatoProviderPayment +/// @notice InstaDapp Connector to compensate Gelato automation-gas Providers. +/// @author Gelato Team +contract ConnectGelatoProviderPayment is ConnectorInterface { + using Address for address payable; + using SafeERC20 for IERC20; + + // solhint-disable-next-line const-name-snakecase + string public constant override name = "ConnectGelatoProviderPayment-v1.0"; + + uint256 internal immutable _id; + + constructor(uint256 id) { + _id = id; + } + + /// @dev Connector Details + function connectorID() + public + view + override + returns (uint256 _type, uint256 id) + { + (_type, id) = (1, _id); // Should put specific value. + } + + /// @notice Transfers automation gas fees to Gelato Provider + /// @dev Gelato Provider risks: + /// - _getId does not match actual InstaMemory provider payment slot + /// - _token balance not in DSA + /// - worthless _token risk + /// @param _provider The Provider who pays the Gelato network for automation. + // This param should be verified / replaced by the ProviderModule in Gelato on-chain. + // In the latter case, it does not matter what address is passed off-chain. + /// @param _token The token used to pay the Provider. + /// @param _amt The amount of _token to pay the Gelato Provider. + /// @param _getId The InstaMemory slot at which the payment amount was stored. + /// @param _setId The InstaMemory slot to save the provider payout amound in. + function payProvider( + address _provider, + address _token, + uint256 _amt, + uint256 _getId, + uint256 _setId + ) public payable virtual { + require( + _provider != address(0x0), + "ConnectGelatoProviderPayment.payProvider:!_provider" + ); + uint256 amt = getUint(_getId, _amt); + setUint(_setId, amt); + _token == ETH + ? payable(_provider).sendValue(amt) + : IERC20(_token).safeTransfer(_provider, amt); + } +} diff --git a/contracts/gelato/conditions/ConditionCompareUintsFromTwoSources.sol b/contracts/contracts/gelato/conditions/ConditionCompareUintsFromTwoSources.sol similarity index 94% rename from contracts/gelato/conditions/ConditionCompareUintsFromTwoSources.sol rename to contracts/contracts/gelato/conditions/ConditionCompareUintsFromTwoSources.sol index ba4dd71..c3f4e84 100644 --- a/contracts/gelato/conditions/ConditionCompareUintsFromTwoSources.sol +++ b/contracts/contracts/gelato/conditions/ConditionCompareUintsFromTwoSources.sol @@ -5,11 +5,10 @@ import { GelatoConditionsStandard } from "@gelatonetwork/core/contracts/conditions/GelatoConditionsStandard.sol"; import {SafeMath} from "@gelatonetwork/core/contracts/external/SafeMath.sol"; -import {IERC20} from "@gelatonetwork/core/contracts/external/IERC20.sol"; import { IGelatoCore } from "@gelatonetwork/core/contracts/gelato_core/interfaces/IGelatoCore.sol"; -import {GelatoBytes} from "../../lib/GelatoBytes.sol"; +import {GelatoBytes} from "../../../lib/GelatoBytes.sol"; /// @notice A general contract for retrieving and comparing 2 uints from 2 contracts. /// @dev This contract only works if the refContracts fns returndata has a uint in @@ -82,7 +81,7 @@ contract ConditionCompareUintsFromTwoSources is GelatoConditionsStandard { ); if (!success) { return - returndata.generateErrorString( + returndata.returnError( "ConditionCompareTwoUints.compare._sourceA:" ); } @@ -92,7 +91,7 @@ contract ConditionCompareUintsFromTwoSources is GelatoConditionsStandard { (success, returndata) = _sourceB.staticcall(_sourceBData); if (!success) { return - returndata.generateErrorString( + returndata.returnError( "ConditionCompareTwoUints.compare._sourceB:" ); } diff --git a/contracts/gelato/conditions/ConditionMakerVaultUnsafe.sol b/contracts/contracts/gelato/conditions/ConditionMakerVaultUnsafe.sol similarity index 92% rename from contracts/gelato/conditions/ConditionMakerVaultUnsafe.sol rename to contracts/contracts/gelato/conditions/ConditionMakerVaultUnsafe.sol index 9e12341..b48858a 100644 --- a/contracts/gelato/conditions/ConditionMakerVaultUnsafe.sol +++ b/contracts/contracts/gelato/conditions/ConditionMakerVaultUnsafe.sol @@ -5,9 +5,11 @@ pragma experimental ABIEncoderV2; import { GelatoConditionsStandard } from "@gelatonetwork/core/contracts/conditions/GelatoConditionsStandard.sol"; -import {wmul, wdiv} from "../../vendor/DSMath.sol"; -import {GelatoBytes} from "../../lib/GelatoBytes.sol"; -import {IInstaMakerResolver} from "../../interfaces/IInstaMakerResolver.sol"; +import {wmul, wdiv} from "../../../vendor/DSMath.sol"; +import {GelatoBytes} from "../../../lib/GelatoBytes.sol"; +import { + IInstaMakerResolver +} from "../../../interfaces/InstaDapp/resolvers/IInstaMakerResolver.sol"; /// @title ConditionMakerVaultUnsafe /// @notice Condition tracking Maker vault collateralization safety requirements. @@ -68,7 +70,7 @@ contract ConditionMakerVaultUnsafe is GelatoConditionsStandard { ); if (!success) { - returndata.revertWithErrorString( + returndata.revertWithError( "ConditionMakerVaultUnsafe.isVaultUnsafe:oracle:" ); } diff --git a/contracts/contracts/gelato/data_generators/DebtBridgeFromMakerForFullRefinance.sol b/contracts/contracts/gelato/data_generators/DebtBridgeFromMakerForFullRefinance.sol new file mode 100644 index 0000000..6b33de5 --- /dev/null +++ b/contracts/contracts/gelato/data_generators/DebtBridgeFromMakerForFullRefinance.sol @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; +pragma experimental ABIEncoderV2; + +import {sub} from "../../../vendor/DSMath.sol"; +import { + _getMakerVaultDebt, + _getMakerVaultCollateralBalance +} from "../../../functions/dapps/FMaker.sol"; +import { + DAI, + CONNECT_MAKER, + CONNECT_COMPOUND, + INSTA_POOL_V2 +} from "../../../constants/CInstaDapp.sol"; +import { + _encodePaybackMakerVault, + _encodedWithdrawMakerVault, + _encodeOpenMakerVault, + _encodedDepositMakerVault, + _encodeBorrowDaiMakerVault +} from "../../../functions/InstaDapp/connectors/FConnectMaker.sol"; +import { + _encodeDepositCompound, + _encodeBorrowCompound +} from "../../../functions/InstaDapp/connectors/FConnectCompound.sol"; +import { + _encodePayGelatoProvider +} from "../../../functions/InstaDapp/connectors/FConnectGelatoProviderPayment.sol"; +import { + _encodeFlashPayback +} from "../../../functions/InstaDapp/connectors/FInstaPoolV2.sol"; +import {_getGelatoProviderFees} from "../../../functions/gelato/FGelato.sol"; +import { + IConnectInstaPoolV2 +} from "../../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol"; + +/// @title DebtBridgeFromMakerForFullRefinance +/// @notice Task Generator contract that generate task for a full refinancing from maker protocol to another protocol (can be Maker). +/// @author Gelato Team +contract DebtBridgeFromMakerForFullRefinance { + uint256 public constant GAS_COST = 1490779 + (14908 * 2); // 1933080 + ~2% (Estimated Value) + + // To retrieve when the connector is deployed and replace with the address of the deployed instance + address public connectGelatoProviderPayment; + + constructor(address _connectGelatoProviderPayment) { + connectGelatoProviderPayment = _connectGelatoProviderPayment; + } + + /// @notice Generate Task for a full refinancing between Maker to Compound. + /// @param _vaultId Id of the unsafe vault of the client. + /// @param _token vault's col token address . + /// @param _provider address of the paying provider. + /// @return targets : flashloan contract address + /// @return datas : calldata for flashloan + function execPayloadForFullRefinanceFromMakerToCompound( + uint256 _vaultId, + address _token, + address _provider + ) public 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 gasFeesPaidFromCol = _getGelatoProviderFees(GAS_COST); + + 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; + _targets[5] = INSTA_POOL_V2; + + bytes[] memory _datas = new bytes[](6); + _datas[0] = _encodePaybackMakerVault(_vaultId, uint256(-1), 0, 0); + _datas[1] = _encodedWithdrawMakerVault(_vaultId, uint256(-1), 0, 0); + _datas[2] = _encodeDepositCompound( + _token, + sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), + 0, + 0 + ); + _datas[3] = _encodeBorrowCompound(DAI, wDaiDebtToMove, 0, 0); + _datas[4] = _encodePayGelatoProvider( + _provider, + _token, + gasFeesPaidFromCol, + 0, + 0 + ); + _datas[5] = _encodeFlashPayback(DAI, wDaiDebtToMove, 0, 0); + + datas = new bytes[](1); + datas[0] = abi.encodeWithSelector( + IConnectInstaPoolV2.flashBorrowAndCast.selector, + DAI, + wDaiDebtToMove, + 0, + abi.encode(_targets, _datas) + ); + } + + /// @notice Generate Task for a full refinancing between Maker (exemple : ETH-A) to Maker (exemple: ETH-B). + /// @param _vaultId Id of the unsafe vault of the client. + /// @param _token vault's col token address . + /// @param _colType colType of the new vault, exemple : ETH-B, ETH-A. + /// @param _provider address of the paying provider. + /// @return targets : flashloan contract address + /// @return datas : calldata for flashloan + function execPayloadForFullRefinanceFromMakerToMaker( + uint256 _vaultId, + address _token, + string memory _colType, + address _provider + ) public 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 gasFeesPaidFromCol = _getGelatoProviderFees(GAS_COST); + + address[] memory _targets = new address[](7); + _targets[0] = CONNECT_MAKER; // payback + _targets[1] = CONNECT_MAKER; // withdraw + _targets[2] = CONNECT_MAKER; // open ETH-B vault + _targets[3] = CONNECT_MAKER; // deposit + _targets[4] = CONNECT_MAKER; // borrow + _targets[5] = connectGelatoProviderPayment; + _targets[6] = targets[0]; + + bytes[] memory _datas = new bytes[](7); + _datas[0] = _encodePaybackMakerVault(_vaultId, uint256(-1), 0, 0); + _datas[1] = _encodedWithdrawMakerVault(_vaultId, uint256(-1), 0, 0); + _datas[2] = _encodeOpenMakerVault(_colType); + _datas[3] = _encodedDepositMakerVault( + 0, + sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), + 0, + 0 + ); + _datas[4] = _encodeBorrowDaiMakerVault(0, wDaiDebtToMove, 0, 0); + _datas[5] = _encodePayGelatoProvider( + _provider, + _token, + gasFeesPaidFromCol, + 0, + 0 + ); + _datas[6] = _encodeFlashPayback(DAI, wDaiDebtToMove, 0, 0); + + datas = new bytes[](1); + datas[0] = abi.encodeWithSelector( + IConnectInstaPoolV2.flashBorrowAndCast.selector, + DAI, + wDaiDebtToMove, + 0, + abi.encode(_targets, _datas) + ); + } + + /// @notice Generate Data for calling execPayloadForFullRefinanceFromMakerToMaker via a static call. + /// @param _vaultId Id of the unsafe vault of the client. + /// @param _token vault's col token address . + /// @param _colType colType of the new vault, exemple : ETH-B, ETH-A. + /// @param _provider address of the paying provider. + /// @return a call data for a static call of execPayloadForFullRefinanceFromMakerToMaker. + function getDebtBridgeFullRefinanceMakerToMakerData( + uint256 _vaultId, + address _token, + string memory _colType, + address _provider + ) public pure returns (bytes memory) { + return + abi.encodeWithSelector( + this.execPayloadForFullRefinanceFromMakerToMaker.selector, + _vaultId, + _token, + _colType, + _provider + ); + } + + /// @notice Generate Data for calling execPayloadForFullRefinanceFromMakerToCompound via a static call. + /// @param _vaultId Id of the unsafe vault of the client. + /// @param _token vault's col token address . + /// @param _provider address of the paying provider. + /// @return a call data for a static call of execPayloadForFullRefinanceFromMakerToMaker. + function getDebtBridgeFullRefinanceMakerToCompoundData( + uint256 _vaultId, + address _token, + address _provider + ) public pure returns (bytes memory) { + return + abi.encodeWithSelector( + this.execPayloadForFullRefinanceFromMakerToCompound.selector, + _vaultId, + _token, + _provider + ); + } +} diff --git a/contracts/contracts/gelato/data_generators/DebtBridgeFromMakerForPartialRefinance.sol b/contracts/contracts/gelato/data_generators/DebtBridgeFromMakerForPartialRefinance.sol new file mode 100644 index 0000000..ac317b5 --- /dev/null +++ b/contracts/contracts/gelato/data_generators/DebtBridgeFromMakerForPartialRefinance.sol @@ -0,0 +1,420 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; +pragma experimental ABIEncoderV2; + +import {GelatoBytes} from "../../../lib/GelatoBytes.sol"; +import {sub, wmul} from "../../../vendor/DSMath.sol"; +import { + _getMakerVaultDebt, + _getMakerVaultCollateralBalance +} from "../../../functions/dapps/FMaker.sol"; +import { + DAI, + CONNECT_MAKER, + CONNECT_COMPOUND, + INSTA_POOL_V2 +} from "../../../constants/CInstaDapp.sol"; +import { + _encodePaybackMakerVault, + _encodedWithdrawMakerVault, + _encodeOpenMakerVault, + _encodedDepositMakerVault, + _encodeBorrowDaiMakerVault +} from "../../../functions/InstaDapp/connectors/FConnectMaker.sol"; +import { + _encodeDepositCompound, + _encodeBorrowCompound +} from "../../../functions/InstaDapp/connectors/FConnectCompound.sol"; +import { + _encodePayGelatoProvider +} from "../../../functions/InstaDapp/connectors/FConnectGelatoProviderPayment.sol"; +import { + _encodeFlashPayback +} from "../../../functions/InstaDapp/connectors/FInstaPoolV2.sol"; +import {_getGelatoProviderFees} from "../../../functions/gelato/FGelato.sol"; +import { + _wCalcCollateralToWithdraw, + _wCalcDebtToRepay +} from "../../../functions/gelato/FGelatoDebtBridge.sol"; +import { + IConnectInstaPoolV2 +} from "../../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol"; + +/// @title DebtBridgeFromMakerForPartialRefinance +/// @notice Task Generator contract that generate task for a full refinancing from maker protocol to another protocol (can be Maker). +/// @author Gelato Team +contract DebtBridgeFromMakerForPartialRefinance { + using GelatoBytes for bytes; + + struct PartialDebtBridgePayload { + uint256 vaultId; + address token; + uint256 wMinColRatioMaker; + uint256 wMinColRatioB; + address priceOracle; + bytes oraclePayload; + address provider; + } + + uint256 public constant GAS_COST = 1490779 + (14908 * 2); // 1933080 + ~2% (Estimated Value) + + // To retrieve when the connector is deployed and replace with the address of the deployed instance + address public connectGelatoProviderPayment; + + constructor(address _connectGelatoProviderPayment) { + connectGelatoProviderPayment = _connectGelatoProviderPayment; + } + + /// @notice Generate Task for a full refinancing between Maker to Compound. + /// @param _payload contain : + // @param _vaultId Id of the unsafe vault of the client. + // @param _token vault's col token address . + // @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position + // @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) + // @param _priceOracle The price oracle contract to supply the collateral price + // e.g. Maker's ETH/USD oracle for ETH collateral pricing. + // @param _oraclePayload The data for making the staticcall to the oracle's read + // method e.g. the function selector of MakerOracle's read function. + // @param _provider address of the paying provider. + /// @return targets : flashloan contract address + /// @return datas : calldata for flashloan + function execPayloadForPartialRefinanceFromMakerToCompound( + PartialDebtBridgePayload calldata _payload + ) public view returns (address[] memory targets, bytes[] memory datas) { + targets = new address[](1); + targets[0] = INSTA_POOL_V2; + + ( + uint256 wDaiDebtToMove, + uint256 wColToWithdrawFromMaker, + uint256 gasFeesPaidFromCol + ) = computeDebtBridge( + _payload.vaultId, + _payload.wMinColRatioMaker, + _payload.wMinColRatioB, + _payload.priceOracle, + _payload.oraclePayload + ); + + 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; + _targets[5] = INSTA_POOL_V2; + + bytes[] memory _datas = new bytes[](6); + _datas[0] = _encodePaybackMakerVault( + _payload.vaultId, + uint256(-1), + 0, + 0 + ); + _datas[1] = _encodedWithdrawMakerVault( + _payload.vaultId, + uint256(-1), + 0, + 0 + ); + _datas[2] = _encodeDepositCompound( + _payload.token, + sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), + 0, + 0 + ); + _datas[3] = _encodeBorrowCompound(DAI, wDaiDebtToMove, 0, 0); + _datas[4] = _encodePayGelatoProvider( + _payload.provider, + _payload.token, + gasFeesPaidFromCol, + 0, + 0 + ); + _datas[5] = _encodeFlashPayback(DAI, wDaiDebtToMove, 0, 0); + + datas = new bytes[](1); + datas[0] = abi.encodeWithSelector( + IConnectInstaPoolV2.flashBorrowAndCast.selector, + DAI, + wDaiDebtToMove, + 0, + abi.encode(_targets, _datas) + ); + } + + /// @notice Generate Task for a full refinancing between Maker (exemple : ETH-A) to Maker (exemple: ETH-B). + /// @param _payload contain : + // @param _vaultId Id of the unsafe vault of the client. + // @param _token vault's col token address . + // @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position + // @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) + // @param _priceOracle The price oracle contract to supply the collateral price + // e.g. Maker's ETH/USD oracle for ETH collateral pricing. + // @param _oraclePayload The data for making the staticcall to the oracle's read + // method e.g. the function selector of MakerOracle's read function. + // @param _provider address of the paying provider. + /// @param _colType colType of the new vault, exemple : ETH-B, ETH-A. + /// @return targets : flashloan contract address + /// @return datas : calldata for flashloan + function execPayloadForPartialRefinanceFromMakerToMaker( + PartialDebtBridgePayload calldata _payload, + string memory _colType + ) public view returns (address[] memory targets, bytes[] memory datas) { + targets = new address[](1); + targets[0] = INSTA_POOL_V2; + + ( + uint256 wDaiDebtToMove, + uint256 wColToWithdrawFromMaker, + uint256 gasFeesPaidFromCol + ) = computeDebtBridge( + _payload.vaultId, + _payload.wMinColRatioMaker, + _payload.wMinColRatioB, + _payload.priceOracle, + _payload.oraclePayload + ); + + address[] memory _targets = new address[](7); + _targets[0] = CONNECT_MAKER; // payback + _targets[1] = CONNECT_MAKER; // withdraw + _targets[2] = CONNECT_MAKER; // open ETH-B vault + _targets[3] = CONNECT_MAKER; // deposit + _targets[4] = CONNECT_MAKER; // borrow + _targets[5] = connectGelatoProviderPayment; + _targets[6] = INSTA_POOL_V2; + + bytes[] memory _datas = new bytes[](7); + _datas[0] = _encodePaybackMakerVault( + _payload.vaultId, + uint256(-1), + 0, + 0 + ); + _datas[1] = _encodedWithdrawMakerVault( + _payload.vaultId, + uint256(-1), + 0, + 0 + ); + _datas[2] = _encodeOpenMakerVault(_colType); + _datas[3] = _encodedDepositMakerVault( + 0, + sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), + 0, + 0 + ); + _datas[4] = _encodeBorrowDaiMakerVault(0, wDaiDebtToMove, 0, 0); + _datas[5] = _encodePayGelatoProvider( + _payload.provider, + _payload.token, + gasFeesPaidFromCol, + 0, + 0 + ); + _datas[6] = _encodeFlashPayback(DAI, wDaiDebtToMove, 0, 0); + + datas = new bytes[](1); + datas[0] = abi.encodeWithSelector( + IConnectInstaPoolV2.flashBorrowAndCast.selector, + DAI, + wDaiDebtToMove, + 0, + abi.encode(_targets, _datas) + ); + } + + /// @notice Computes values needed for DebtBridge Maker->ProtocolB + /// @dev Use wad for colRatios. + /// @param _vaultId The id of the makerDAO vault. + /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position + /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) + /// @param _priceOracle The price oracle contract to supply the collateral price + /// e.g. Maker's ETH/USD oracle for ETH collateral pricing. + /// @param _oraclePayload The data for making the staticcall to the oracle's read + /// method e.g. the function selector of MakerOracle's read function. + /// @return wDaiDebtToMove DAI Debt (wad) to: flashBorrow->repay Maker->withdraw from B->flashPayback. + /// @return wColToWithdrawFromMaker (wad) to: withdraw from Maker and deposit on B. + /// @return gasFeesPaidFromCol Gelato automation-gas-fees paid from user's collateral + // solhint-disable function-max-lines + function computeDebtBridge( + uint256 _vaultId, + uint256 _wMinColRatioMaker, + uint256 _wMinColRatioB, + address _priceOracle, + bytes calldata _oraclePayload + ) + public + view + virtual + returns ( + uint256 wDaiDebtToMove, + uint256 wColToWithdrawFromMaker, + uint256 gasFeesPaidFromCol + ) + { + uint256 wColPrice; + + // Stack too deep + { + (bool success, bytes memory returndata) = _priceOracle.staticcall( + _oraclePayload + ); + + if (!success) { + returndata.revertWithError( + "ConnectGelatoPartialDebtBridgeFromMaker.computeDebtBridge:oracle:" + ); + } + + wColPrice = abi.decode(returndata, (uint256)); + } + + // TO DO: add fee mechanism for non-ETH collateral debt bridge + // uint256 gasFeesPaidFromCol = _mul(GAS_COST, wmul(_getGelatoGasPrice(), latestPrice)); + gasFeesPaidFromCol = _getGelatoProviderFees(GAS_COST); + + uint256 wPricedCol = wmul( + sub(_getMakerVaultCollateralBalance(_vaultId), gasFeesPaidFromCol), + wColPrice + ); + + uint256 wDaiDebtOnMaker = _getMakerVaultDebt(_vaultId); + + wColToWithdrawFromMaker = wCalcCollateralToWithdraw( + _wMinColRatioMaker, + _wMinColRatioB, + wColPrice, + wPricedCol, + wDaiDebtOnMaker + ); + + wDaiDebtToMove = wCalcDebtToRepay( + _wMinColRatioMaker, + _wMinColRatioB, + wPricedCol, + wDaiDebtOnMaker + ); + } + + /// @notice Compute collateral (wad) to move from Maker to B. + /// @dev Convenience API for frontends - check _wCalcDebtToRepay for implementation + /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position + /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) + /// @param _wColPrice Price of the collateral (wad) in oracle price units. + /// @param _wPricedCol Collateral to move (wad) valued in oracle price. + /// @param _wDaiDebtOnMaker Amount of DAI (wad) borrowed from Maker. + /// @return collateral to withdraw from A in wad + function wCalcCollateralToWithdraw( + uint256 _wMinColRatioMaker, + uint256 _wMinColRatioB, + uint256 _wColPrice, + uint256 _wPricedCol, + uint256 _wDaiDebtOnMaker + ) public pure virtual returns (uint256) { + return + _wCalcCollateralToWithdraw( + _wMinColRatioMaker, + _wMinColRatioB, + _wColPrice, + _wPricedCol, + _wDaiDebtOnMaker + ); + } + + /// @notice Compute debt (wad) to flashBorrow->repay Maker->withdraw from B->flashPayback + /// @dev Convenience API for frontends - check _wCalcDebtToRepay for implementation. + /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position + /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) + /// @param _wPricedCol Collateral to move (wad) valued in oracle price. + /// @param _wDaiDebtOnMaker Amount of DAI (wad) borrowed from Maker. + /// @return amount of borrowed token to pay back in wad + function wCalcDebtToRepay( + uint256 _wMinColRatioMaker, + uint256 _wMinColRatioB, + uint256 _wPricedCol, + uint256 _wDaiDebtOnMaker + ) public pure virtual returns (uint256) { + return + _wCalcDebtToRepay( + _wMinColRatioMaker, + _wMinColRatioB, + _wPricedCol, + _wDaiDebtOnMaker + ); + } + + /// @notice Generate Data for calling execPayloadForPartialRefinanceFromMakerToMaker via a static call. + /// @param _vaultId Id of the unsafe vault of the client. + /// @param _token vault's col token address . + /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position + /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) + /// @param _priceOracle The price oracle contract to supply the collateral price + /// e.g. Maker's ETH/USD oracle for ETH collateral pricing. + /// @param _oraclePayload The data for making the staticcall to the oracle's read + /// method e.g. the function selector of MakerOracle's read function. + /// @param _colType colType of the new vault, exemple : ETH-B, ETH-A. + /// @param _provider address of the paying provider. + /// @return a call data for a static call of execPayloadForPartialRefinanceFromMakerToMaker. + function getDebtBridgePartialRefinanceMakerToMakerData( + uint256 _vaultId, + address _token, + uint256 _wMinColRatioMaker, + uint256 _wMinColRatioB, + address _priceOracle, + bytes calldata _oraclePayload, + string memory _colType, + address _provider + ) public pure returns (bytes memory) { + return + abi.encodeWithSelector( + this.execPayloadForPartialRefinanceFromMakerToMaker.selector, + PartialDebtBridgePayload({ + vaultId: _vaultId, + token: _token, + wMinColRatioMaker: _wMinColRatioMaker, + wMinColRatioB: _wMinColRatioB, + priceOracle: _priceOracle, + oraclePayload: _oraclePayload, + provider: _provider + }), + _colType + ); + } + + /// @notice Generate Data for calling execPayloadForPartialRefinanceFromMakerToCompound via a static call. + /// @param _vaultId Id of the unsafe vault of the client. + /// @param _token vault's col token address . + /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position + /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) + /// @param _priceOracle The price oracle contract to supply the collateral price + /// e.g. Maker's ETH/USD oracle for ETH collateral pricing. + /// @param _oraclePayload The data for making the staticcall to the oracle's read + /// method e.g. the function selector of MakerOracle's read function. + /// @param _provider address of the paying provider. + /// @return a call data for a static call of execPayloadForPartialRefinanceFromMakerToMaker. + function getDebtBridgePartialRefinanceMakerToCompoundData( + uint256 _vaultId, + address _token, + uint256 _wMinColRatioMaker, + uint256 _wMinColRatioB, + address _priceOracle, + bytes calldata _oraclePayload, + address _provider + ) public pure returns (bytes memory) { + return + abi.encodeWithSelector( + this.execPayloadForPartialRefinanceFromMakerToCompound.selector, + PartialDebtBridgePayload({ + vaultId: _vaultId, + token: _token, + wMinColRatioMaker: _wMinColRatioMaker, + wMinColRatioB: _wMinColRatioB, + priceOracle: _priceOracle, + oraclePayload: _oraclePayload, + provider: _provider + }) + ); + } +} diff --git a/contracts/gelato/ProviderModuleDSAFromMakerToCompound.sol b/contracts/contracts/gelato/provider_modules/ProviderModuleDSAFromMakerToCompound.sol similarity index 90% rename from contracts/gelato/ProviderModuleDSAFromMakerToCompound.sol rename to contracts/contracts/gelato/provider_modules/ProviderModuleDSAFromMakerToCompound.sol index 7d3891b..34c033e 100644 --- a/contracts/gelato/ProviderModuleDSAFromMakerToCompound.sol +++ b/contracts/contracts/gelato/provider_modules/ProviderModuleDSAFromMakerToCompound.sol @@ -8,18 +8,16 @@ import { import { Task } from "@gelatonetwork/core/contracts/gelato_core/interfaces/IGelatoCore.sol"; -import {AccountInterface} from "../interfaces/InstaDapp.sol"; +import {AccountInterface} from "../../../interfaces/InstaDapp/IInstaDapp.sol"; import { DebtBridgeFromMakerForFullRefinance -} from "../gelato/DebtBridgeFromMakerForFullRefinance.sol"; -import { - ConnectGelatoDebtBridge -} from "../connectors/ConnectGelatoDebtBridge.sol"; +} from "../../gelato/data_generators/DebtBridgeFromMakerForFullRefinance.sol"; +import {ConnectGelatoData} from "../../connectors/ConnectGelatoData.sol"; /// @notice Gelato Provider Module for the InstaDapp DSA /// @dev Used by Provider to sanity check any third-party Tasks they pay for /// @author Gelato Network Team -contract ProviderModuleDSAFromMakerToCompound is GelatoProviderModuleStandard { +contract ProviderModuleDsaFromMakerToCompound is GelatoProviderModuleStandard { /// @dev DSA must have gelatoCore as auth and gelatoCore is emitted as origin of cast address public immutable gelatoCore; @@ -82,7 +80,7 @@ contract ProviderModuleDSAFromMakerToCompound is GelatoProviderModuleStandard { ) public view virtual override returns (bytes memory, bool) { require( _task.actions.length == 1, - "ProviderModuleDSAFromMakerToCompound.execPayload: Task should 1 action." + "ProviderModuleDsaFromMakerToCompound.execPayload: Task should 1 action." ); address[] memory targets = new address[](_task.actions.length); targets[0] = _task.actions[0].addr; @@ -106,15 +104,14 @@ contract ProviderModuleDSAFromMakerToCompound is GelatoProviderModuleStandard { pure returns (bytes memory) { - (address target, ) = abi.decode(_data[4:], (address, bytes)); - + address target = abi.decode(_data[4:36], (address)); (uint256 vaultId, address token, ) = abi.decode( _data[104:], (uint256, address, address) ); return abi.encodeWithSelector( - ConnectGelatoDebtBridge.computeRefinanceDataAndCast.selector, + ConnectGelatoData.getDataAndCast.selector, target, abi.encodeWithSelector( DebtBridgeFromMakerForFullRefinance diff --git a/contracts/gelato/ProviderModuleDSAFromMakerToMaker.sol b/contracts/contracts/gelato/provider_modules/ProviderModuleDSAFromMakerToMaker.sol similarity index 90% rename from contracts/gelato/ProviderModuleDSAFromMakerToMaker.sol rename to contracts/contracts/gelato/provider_modules/ProviderModuleDSAFromMakerToMaker.sol index 7da7a7b..082e141 100644 --- a/contracts/gelato/ProviderModuleDSAFromMakerToMaker.sol +++ b/contracts/contracts/gelato/provider_modules/ProviderModuleDSAFromMakerToMaker.sol @@ -8,18 +8,16 @@ import { import { Task } from "@gelatonetwork/core/contracts/gelato_core/interfaces/IGelatoCore.sol"; -import {AccountInterface} from "../interfaces/InstaDapp.sol"; +import {AccountInterface} from "../../../interfaces/InstaDapp/IInstaDapp.sol"; import { DebtBridgeFromMakerForFullRefinance -} from "../gelato/DebtBridgeFromMakerForFullRefinance.sol"; -import { - ConnectGelatoDebtBridge -} from "../connectors/ConnectGelatoDebtBridge.sol"; +} from "../../gelato/data_generators/DebtBridgeFromMakerForFullRefinance.sol"; +import {ConnectGelatoData} from "../../connectors/ConnectGelatoData.sol"; /// @notice Gelato Provider Module for the InstaDapp DSA /// @dev Used by Provider to sanity check any third-party Tasks they pay for /// @author Gelato Network Team -contract ProviderModuleDSAFromMakerToMaker is GelatoProviderModuleStandard { +contract ProviderModuleDsaFromMakerToMaker is GelatoProviderModuleStandard { /// @dev DSA must have gelatoCore as auth and gelatoCore is emitted as origin of cast address public immutable gelatoCore; @@ -82,7 +80,7 @@ contract ProviderModuleDSAFromMakerToMaker is GelatoProviderModuleStandard { ) public view virtual override returns (bytes memory, bool) { require( _task.actions.length == 1, - "ProviderModuleDSAFromMakerToMaker.execPayload: Task should 1 action." + "ProviderModuleDsaFromMakerToMaker.execPayload: Task should 1 action." ); address[] memory targets = new address[](_task.actions.length); targets[0] = _task.actions[0].addr; @@ -106,7 +104,7 @@ contract ProviderModuleDSAFromMakerToMaker is GelatoProviderModuleStandard { pure returns (bytes memory) { - (address target, ) = abi.decode(_data[4:], (address, bytes)); + address target = abi.decode(_data[4:36], (address)); (uint256 vaultId, address token, string memory colType, ) = abi.decode( _data[104:], @@ -115,7 +113,7 @@ contract ProviderModuleDSAFromMakerToMaker is GelatoProviderModuleStandard { return abi.encodeWithSelector( - ConnectGelatoDebtBridge.computeRefinanceDataAndCast.selector, + ConnectGelatoData.getDataAndCast.selector, target, abi.encodeWithSelector( DebtBridgeFromMakerForFullRefinance diff --git a/contracts/mocks/MockCDAI.sol b/contracts/contracts/mocks/MockCDAI.sol similarity index 100% rename from contracts/mocks/MockCDAI.sol rename to contracts/contracts/mocks/MockCDAI.sol diff --git a/contracts/mocks/MockDSR.sol b/contracts/contracts/mocks/MockDSR.sol similarity index 100% rename from contracts/mocks/MockDSR.sol rename to contracts/contracts/mocks/MockDSR.sol diff --git a/contracts/contracts/resolvers/MakerResolver.sol b/contracts/contracts/resolvers/MakerResolver.sol new file mode 100644 index 0000000..cf8c738 --- /dev/null +++ b/contracts/contracts/resolvers/MakerResolver.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import { + _getMakerVaultDebt, + _getMakerVaultCollateralBalance +} from "../../functions/dapps/FMaker.sol"; + +contract MakerResolver { + /// @dev Return Debt in wad of the vault associated to the vaultId. + function getMakerVaultDebt(uint256 _vaultId) public view returns (uint256) { + return _getMakerVaultDebt(_vaultId); + } + + /// @dev Return Collateral in wad of the vault associated to the vaultId. + function getMakerVaultCollateralBalance(uint256 _vaultId) + public + view + returns (uint256) + { + return _getMakerVaultCollateralBalance(_vaultId); + } +} diff --git a/contracts/resolvers/PriceOracleResolver.sol b/contracts/contracts/resolvers/PriceOracleResolver.sol similarity index 94% rename from contracts/resolvers/PriceOracleResolver.sol rename to contracts/contracts/resolvers/PriceOracleResolver.sol index b09270e..8d3a1e1 100644 --- a/contracts/resolvers/PriceOracleResolver.sol +++ b/contracts/contracts/resolvers/PriceOracleResolver.sol @@ -2,8 +2,8 @@ pragma solidity 0.7.4; pragma experimental ABIEncoderV2; -import {Ownable} from "../vendor/Ownable.sol"; -import {GelatoBytes} from "../lib/GelatoBytes.sol"; +import {Ownable} from "../../vendor/Ownable.sol"; +import {GelatoBytes} from "../../lib/GelatoBytes.sol"; /// @title PriceOracleResolver /// @notice Contract with convenience methods to retrieve oracle addresses or to mock test. @@ -63,7 +63,7 @@ contract PriceOracleResolver is Ownable { oraclePayload[_oracle] ); if (!success) - returndata.revertWithErrorString("PriceOracleResolver.getPrice:"); + returndata.revertWithError("PriceOracleResolver.getPrice:"); return abi.decode(returndata, (uint256)); } } diff --git a/contracts/functions/InstaDapp/FInstaDapp.sol b/contracts/functions/InstaDapp/FInstaDapp.sol new file mode 100644 index 0000000..d4bf805 --- /dev/null +++ b/contracts/functions/InstaDapp/FInstaDapp.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import {MemoryInterface} from "../../interfaces/InstaDapp/IInstaDapp.sol"; +import {INSTA_MEMORY} from "../../constants/CInstaDapp.sol"; + +function setUint(uint256 setId, uint256 val) { + if (setId != 0) MemoryInterface(INSTA_MEMORY).setUint(setId, val); +} + +function getUint(uint256 getId, uint256 val) returns (uint256 returnVal) { + returnVal = getId == 0 ? val : MemoryInterface(INSTA_MEMORY).getUint(getId); +} diff --git a/contracts/functions/InstaDapp/connectors/FConnectCompound.sol b/contracts/functions/InstaDapp/connectors/FConnectCompound.sol new file mode 100644 index 0000000..eb9b019 --- /dev/null +++ b/contracts/functions/InstaDapp/connectors/FConnectCompound.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import { + IConnectCompound +} from "../../../interfaces/InstaDapp/connectors/IConnectCompound.sol"; + +function _encodeDepositCompound( + address _token, + uint256 _amt, + uint256 _getId, + uint256 _setId +) pure returns (bytes memory) { + return + abi.encodeWithSelector( + IConnectCompound.deposit.selector, + _token, + _amt, + _getId, + _setId + ); +} + +function _encodeBorrowCompound( + address _token, + uint256 _amt, + uint256 _getId, + uint256 _setId +) pure returns (bytes memory) { + return + abi.encodeWithSelector( + IConnectCompound.borrow.selector, + _token, + _amt, + _getId, + _setId + ); +} diff --git a/contracts/functions/InstaDapp/connectors/FConnectGelatoProviderPayment.sol b/contracts/functions/InstaDapp/connectors/FConnectGelatoProviderPayment.sol new file mode 100644 index 0000000..2772168 --- /dev/null +++ b/contracts/functions/InstaDapp/connectors/FConnectGelatoProviderPayment.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import { + IConnectGelatoProviderPayment +} from "../../../interfaces/InstaDapp/connectors/IConnectGelatoProviderPayment.sol"; + +function _encodePayGelatoProvider( + address _provider, + address _token, + uint256 _amt, + uint256 _getId, + uint256 _setId +) pure returns (bytes memory) { + return + abi.encodeWithSelector( + IConnectGelatoProviderPayment.payProvider.selector, + _provider, + _token, + _amt, + _getId, + _setId + ); +} diff --git a/contracts/functions/InstaDapp/connectors/FConnectMaker.sol b/contracts/functions/InstaDapp/connectors/FConnectMaker.sol new file mode 100644 index 0000000..b629807 --- /dev/null +++ b/contracts/functions/InstaDapp/connectors/FConnectMaker.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import { + IConnectMaker +} from "../../../interfaces/InstaDapp/connectors/IConnectMaker.sol"; + +function _encodeOpenMakerVault(string memory _colType) + pure + returns (bytes memory) +{ + return abi.encodeWithSelector(IConnectMaker.open.selector, _colType); +} + +function _encodeBorrowDaiMakerVault( + uint256 _vaultId, + uint256 _amt, + uint256 _getId, + uint256 _setId +) pure returns (bytes memory) { + return + abi.encodeWithSelector( + IConnectMaker.borrow.selector, + _vaultId, + _amt, + _getId, + _setId + ); +} + +function _encodedDepositMakerVault( + uint256 _vaultId, + uint256 _amt, + uint256 _getId, + uint256 _setId +) pure returns (bytes memory) { + return + abi.encodeWithSelector( + IConnectMaker.deposit.selector, + _vaultId, + _amt, + _getId, + _setId + ); +} + +function _encodePaybackMakerVault( + uint256 _vaultId, + uint256 _amt, + uint256 _getId, + uint256 _setId +) pure returns (bytes memory) { + return + abi.encodeWithSelector( + IConnectMaker.payback.selector, + _vaultId, + _amt, + _getId, + _setId + ); +} + +function _encodedWithdrawMakerVault( + uint256 _vaultId, + uint256 _amt, + uint256 _getId, + uint256 _setId +) pure returns (bytes memory) { + return + abi.encodeWithSelector( + IConnectMaker.withdraw.selector, + _vaultId, + _amt, + _getId, + _setId + ); +} diff --git a/contracts/functions/InstaDapp/connectors/FInstaPoolV2.sol b/contracts/functions/InstaDapp/connectors/FInstaPoolV2.sol new file mode 100644 index 0000000..57ed662 --- /dev/null +++ b/contracts/functions/InstaDapp/connectors/FInstaPoolV2.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import { + IConnectInstaPoolV2 +} from "../../../interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol"; + +function _encodeFlashPayback( + address _token, + uint256 _amt, + uint256 _getId, + uint256 _setId +) pure returns (bytes memory) { + return + abi.encodeWithSelector( + IConnectInstaPoolV2.flashPayback.selector, + _token, + _amt, + _getId, + _setId + ); +} diff --git a/contracts/functions/dapps/FMaker.sol b/contracts/functions/dapps/FMaker.sol new file mode 100644 index 0000000..c17e85b --- /dev/null +++ b/contracts/functions/dapps/FMaker.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import {IManager} from "../../interfaces/Maker/IManager.sol"; +import {IVat} from "../../interfaces/Maker/IVat.sol"; +import {RAY, sub, mul} from "../../vendor/DSMath.sol"; + +function _getMcdManager() pure returns (address) { + return 0x5ef30b9986345249bc32d8928B7ee64DE9435E39; +} + +function _getManager() pure returns (IManager) { + return IManager(_getMcdManager()); +} + +function _getMakerVaultDebt(uint256 _vaultId) view returns (uint256 wad) { + IManager cdpManager = _getManager(); + + (bytes32 ilk, address urn) = _getVaultData(cdpManager, _vaultId); + IVat vat = IVat(cdpManager.vat()); + (, uint256 rate, , , ) = vat.ilks(ilk); + (, uint256 art) = vat.urns(ilk, urn); + uint256 dai = vat.dai(urn); + + uint256 rad = sub(mul(art, rate), dai); + wad = rad / RAY; + + wad = mul(wad, RAY) < rad ? wad + 1 : wad; +} + +function _getMakerVaultCollateralBalance(uint256 _vaultId) + view + returns (uint256) +{ + IManager cdpManager = _getManager(); + + IVat vat = IVat(cdpManager.vat()); + (bytes32 ilk, address urn) = _getVaultData(cdpManager, _vaultId); + (uint256 ink, ) = vat.urns(ilk, urn); + + return ink; +} + +function _getVaultData(IManager cdpManager, uint256 vault) + view + returns (bytes32 ilk, address urn) +{ + ilk = cdpManager.ilks(vault); + urn = cdpManager.urns(vault); +} diff --git a/contracts/functions/gelato/FGelato.sol b/contracts/functions/gelato/FGelato.sol new file mode 100644 index 0000000..83d4948 --- /dev/null +++ b/contracts/functions/gelato/FGelato.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import {GELATO_GAS_PRICE_ORACLE} from "../../constants/CGelato.sol"; +import {mul} from "../../vendor/DSMath.sol"; + +function _getGelatoGasPrice() view returns (uint256) { + return uint256(GELATO_GAS_PRICE_ORACLE.latestAnswer()); +} + +function _getGelatoProviderFees(uint256 _gas) view returns (uint256) { + return mul(_gas, _getGelatoGasPrice()); +} diff --git a/contracts/functions/gelato/FGelatoDebtBridge.sol b/contracts/functions/gelato/FGelatoDebtBridge.sol new file mode 100644 index 0000000..dba5563 --- /dev/null +++ b/contracts/functions/gelato/FGelatoDebtBridge.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.7.4; + +import {sub, wmul, wdiv} from "../../vendor/DSMath.sol"; + +function _wCalcCollateralToWithdraw( + uint256 _wMinColRatioMaker, + uint256 _wMinColRatioB, + uint256 _wColPrice, + uint256 _wPricedCol, + uint256 _wDaiDebtOnMaker +) pure returns (uint256) { + return + wdiv( + sub( + _wPricedCol, + wdiv( + sub( + wmul(_wMinColRatioMaker, _wPricedCol), + wmul( + _wMinColRatioMaker, + wmul(_wMinColRatioB, _wDaiDebtOnMaker) + ) + ), + sub(_wMinColRatioMaker, _wMinColRatioB) + ) + ), + _wColPrice + ); +} + +function _wCalcDebtToRepay( + uint256 _wMinColRatioMaker, + uint256 _wMinColRatioB, + uint256 _wPricedCol, + uint256 _wDaiDebtOnMaker +) pure returns (uint256) { + return + sub( + _wDaiDebtOnMaker, + wmul( + wdiv(1e18, _wMinColRatioMaker), + wdiv( + sub( + wmul(_wMinColRatioMaker, _wPricedCol), + wmul( + _wMinColRatioMaker, + wmul(_wMinColRatioB, _wDaiDebtOnMaker) + ) + ), + sub(_wMinColRatioMaker, _wMinColRatioB) + ) + ) + ); +} diff --git a/contracts/gelato/DebtBridgeFromMakerForFullRefinance.sol b/contracts/gelato/DebtBridgeFromMakerForFullRefinance.sol deleted file mode 100644 index 705d740..0000000 --- a/contracts/gelato/DebtBridgeFromMakerForFullRefinance.sol +++ /dev/null @@ -1,515 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.7.4; -pragma experimental ABIEncoderV2; -import {sub, mul, wmul, RAY} from "../vendor/DSMath.sol"; -import {IGelatoTaskGenerator} from "../interfaces/IGelatoTaskGenerator.sol"; -import {IConnectMaker} from "../interfaces/IConnectMaker.sol"; -import {IConnectCompound} from "../interfaces/IConnectCompound.sol"; -import {IGelatoGasPriceOracle} from "../interfaces/IGelatoGasPriceOracle.sol"; -import {IFlashLoan} from "../interfaces/IFlashLoan.sol"; -import {DSAInterface} from "../interfaces/DSAInterface.sol"; -import { - IConnectGelatoProviderPayment -} from "../interfaces/IConnectGelatoProviderPayment.sol"; -import {IManager} from "../interfaces/IManager.sol"; -import {IVat} from "../interfaces/IVat.sol"; - -abstract contract Helpers { - /** - * @dev Return Maker Connector address. - */ - function _getConnectMaker() internal pure returns (address) { - return 0xac02030d8a8F49eD04b2f52C394D3F901A10F8A9; - } - - /** - * @dev Return Compound Connector address. - */ - function _getConnectCompound() internal pure returns (address) { - return 0x07F81230d73a78f63F0c2A3403AD281b067d28F8; - } - - /** - * @dev Return Default Ether address. - */ - function _getEthAddr() internal pure returns (address) { - return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; - } - - /** - * @dev Return Default Ether address. - */ - function _getDaiTokenAddr() internal pure returns (address) { - return 0x6B175474E89094C44Da98b954EedeAC495271d0F; - } - - /** - * @dev Return Insta pool V2 connector. - */ - function _getInstaPoolV2Addr() internal pure returns (address) { - return 0x3150e5A805577366816A1ddc7330c6Ea17070c05; - } - - /** - * @dev Return Maker MCD Manager address. - */ - function _getMcdManager() internal pure returns (address) { - return 0x5ef30b9986345249bc32d8928B7ee64DE9435E39; - } -} - -abstract contract GelatoHelpers is Helpers { - // To retrieve when the connector is deployed and replace with the address of the deployed instance - address public gelatoPaymentConnectorAddr; - - /** - * @dev Return Gelato Payment Connector. - */ - function _getConnectGelatoProviderPaymentAddr() - internal - view - returns (address) - { - return gelatoPaymentConnectorAddr; - } - - /** - * @dev Return Gelato gas price oracle. - */ - function _getGelatoGasPriceOracle() internal pure returns (address) { - return 0x169E633A2D1E6c10dD91238Ba11c4A708dfEF37C; - } - - /** - * @dev Return Gas price. - */ - function _getGelatoGasPrice() internal view returns (uint256) { - return - uint256( - IGelatoGasPriceOracle(_getGelatoGasPriceOracle()).latestAnswer() - ); - } -} - -abstract contract MakerResolver is GelatoHelpers { - /** - * @dev Return Debt in wad of the vault associated to the vaultId. - */ - function getMakerVaultDebt(uint256 _vaultId) - public - view - returns (uint256 wad) - { - IManager cdpManager = _getManager(); - - (bytes32 ilk, address urn) = _getVaultData(cdpManager, _vaultId); - IVat vat = IVat(cdpManager.vat()); - (, uint256 rate, , , ) = vat.ilks(ilk); - (, uint256 art) = vat.urns(ilk, urn); - uint256 dai = vat.dai(urn); - - uint256 rad = sub(mul(art, rate), dai); - wad = rad / RAY; - - wad = mul(wad, RAY) < rad ? wad + 1 : wad; - } - - /** - * @dev Return Collateral in wad of the vault associated to the vaultId. - */ - function getMakerVaultCollateralBalance(uint256 _vaultId) - public - view - returns (uint256) - { - IManager cdpManager = _getManager(); - - IVat vat = IVat(cdpManager.vat()); - (bytes32 ilk, address urn) = _getVaultData(cdpManager, _vaultId); - (uint256 ink, ) = vat.urns(ilk, urn); - - return ink; - } - - function _getVaultData(IManager cdpManager, uint256 vault) - internal - view - returns (bytes32 ilk, address urn) - { - ilk = cdpManager.ilks(vault); - urn = cdpManager.urns(vault); - } - - function _getManager() internal pure returns (IManager) { - return IManager(_getMcdManager()); - } -} - -abstract contract DebtBridgeFromMakerForFullRefinanceResolver is MakerResolver { - function execPayloadForFullRefinanceFromMakerToMaker( - uint256 _vaultId, - address _token, - string memory _colType, - address _provider - ) public view virtual returns (address, bytes memory); - - function execPayloadForFullRefinanceFromMakerToCompound( - uint256 _vaultId, - address _token, - address _provider - ) public view virtual returns (address, bytes memory); - - /// @notice Generate Data for calling execPayloadForFullRefinanceFromMakerToMaker via a static call. - /// @param _vaultId Id of the unsafe vault of the client. - /// @param _token vault's col token address . - /// @param _colType colType of the new vault, exemple : ETH-B, ETH-A. - /// @param _provider address of the paying provider. - /// @return a call data for a static call of execPayloadForFullRefinanceFromMakerToMaker. - function getDebtBridgeFullRefinanceMakerToMakerData( - uint256 _vaultId, - address _token, - string memory _colType, - address _provider - ) public pure returns (bytes memory) { - return - abi.encodeWithSelector( - this.execPayloadForFullRefinanceFromMakerToMaker.selector, - _vaultId, - _token, - _colType, - _provider - ); - } - - /// @notice Generate Data for calling execPayloadForFullRefinanceFromMakerToCompound via a static call. - /// @param _vaultId Id of the unsafe vault of the client. - /// @param _token vault's col token address . - /// @param _provider address of the paying provider. - /// @return a call data for a static call of execPayloadForFullRefinanceFromMakerToMaker. - function getDebtBridgeFullRefinanceMakerToCompoundData( - uint256 _vaultId, - address _token, - address _provider - ) public pure returns (bytes memory) { - return - abi.encodeWithSelector( - this.execPayloadForFullRefinanceFromMakerToCompound.selector, - _vaultId, - _token, - _provider - ); - } -} - -/// @title DebtBridgeFromMakerForFullRefinance -/// @notice Task Generator contract that generate task for a full refinancing from maker protocol to another protocol (can be Maker). -/// @author Gelato Team -contract DebtBridgeFromMakerForFullRefinance is - DebtBridgeFromMakerForFullRefinanceResolver -{ - uint256 public constant GAS_COST = 1490779 + (14908 * 2); // 1933080 + ~2% (Estimated Value) - - constructor(address _gelatoPaymentConnectorAddr) { - gelatoPaymentConnectorAddr = _gelatoPaymentConnectorAddr; - } - - /// @notice Generate Task for a full refinancing between Maker to Compound. - /// @param _vaultId Id of the unsafe vault of the client. - /// @param _token vault's col token address . - /// @param _provider address of the paying provider. - /// @return a target the flashloan contract address and the corresponding call data. - function execPayloadForFullRefinanceFromMakerToCompound( - uint256 _vaultId, - address _token, - address _provider - ) public view override returns (address, bytes memory) { - address target = _getInstaPoolV2Addr(); - address connectMaker = _getConnectMaker(); - address connectCompound = _getConnectCompound(); - address daiToken = _getDaiTokenAddr(); - - uint256 wDaiDebtToMove = getMakerVaultDebt(_vaultId); - uint256 wColToWithdrawFromMaker = getMakerVaultCollateralBalance( - _vaultId - ); - uint256 gasFeesPaidFromCol = _getGelatoProviderFees(); - - address[] memory targets = new address[](6); - targets[0] = connectMaker; // payback - targets[1] = connectMaker; // withdraw - targets[2] = connectCompound; // deposit - targets[3] = connectCompound; // borrow - targets[4] = _getConnectGelatoProviderPaymentAddr(); - targets[5] = target; - - bytes[] memory datas = new bytes[](6); - datas[0] = _encodedDataForPayBackMakerVault( - _vaultId, - uint256(-1), - 0, - 0 - ); - datas[1] = _encodedDataForWithdrawMakerVault( - _vaultId, - uint256(-1), - 0, - 0 - ); - datas[2] = _encodedDataForDepositOnCompound( - _token, - sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), - 0, - 0 - ); - datas[3] = _encodedDataForBorrowDaiOnCompound( - daiToken, - wDaiDebtToMove, - 0, - 0 - ); - datas[4] = _encodeDataForPayingProvider( - _provider, - _token, - gasFeesPaidFromCol, - 0, - 0 - ); - datas[5] = _encodeDataForPayingBackDyDx(daiToken, wDaiDebtToMove, 0, 0); - - bytes memory flashloanCallData = abi.encode(targets, datas); - bytes memory callData = abi.encodeWithSelector( - IFlashLoan.flashBorrowAndCast.selector, - daiToken, - wDaiDebtToMove, - 0, - flashloanCallData - ); - - return (target, callData); - } - - /// @notice Generate Task for a full refinancing between Maker (exemple : ETH-A) to Maker (exemple: ETH-B). - /// @param _vaultId Id of the unsafe vault of the client. - /// @param _token vault's col token address . - /// @param _colType colType of the new vault, exemple : ETH-B, ETH-A. - /// @param _provider address of the paying provider. - /// @return a target the flashloan contract address and the corresponding call data. - function execPayloadForFullRefinanceFromMakerToMaker( - uint256 _vaultId, - address _token, - string memory _colType, - address _provider - ) public view override returns (address, bytes memory) { - address target = _getInstaPoolV2Addr(); - address connectMaker = _getConnectMaker(); - address daiToken = _getDaiTokenAddr(); - - uint256 wDaiDebtToMove = getMakerVaultDebt(_vaultId); - uint256 wColToWithdrawFromMaker = getMakerVaultCollateralBalance( - _vaultId - ); - uint256 gasFeesPaidFromCol = _getGelatoProviderFees(); - - address[] memory targets = new address[](7); - targets[0] = connectMaker; // payback - targets[1] = connectMaker; // withdraw - targets[2] = connectMaker; // open ETH-B vault - targets[3] = connectMaker; // deposit - targets[4] = connectMaker; // borrow - targets[5] = _getConnectGelatoProviderPaymentAddr(); - targets[6] = target; - - bytes[] memory datas = new bytes[](7); - datas[0] = _encodedDataForPayBackMakerVault( - _vaultId, - uint256(-1), - 0, - 0 - ); - datas[1] = _encodedDataForWithdrawMakerVault( - _vaultId, - uint256(-1), - 0, - 0 - ); - datas[2] = _encodedDataForOpenAMakerVault(_colType); - datas[3] = _encodedDataForDepositOnMakerVault( - 0, - sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), - 0, - 0 - ); - datas[4] = _encodedDataForBorrowDaiOnMakerVault( - 0, - wDaiDebtToMove, - 0, - 0 - ); - datas[5] = _encodeDataForPayingProvider( - _provider, - _token, - gasFeesPaidFromCol, - 0, - 0 - ); - datas[6] = _encodeDataForPayingBackDyDx(daiToken, wDaiDebtToMove, 0, 0); - - bytes memory flashloanCallData = abi.encode(targets, datas); - bytes memory callData = abi.encodeWithSelector( - IFlashLoan.flashBorrowAndCast.selector, - daiToken, - wDaiDebtToMove, - 0, - flashloanCallData - ); - - return (target, callData); - } - - function _encodedDataForPayBackMakerVault( - uint256 _vaultId, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectMaker.payback.selector, - _vaultId, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForWithdrawMakerVault( - uint256 _vaultId, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectMaker.withdraw.selector, - _vaultId, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForOpenAMakerVault(string memory _colType) - internal - pure - returns (bytes memory) - { - return abi.encodeWithSelector(IConnectMaker.open.selector, _colType); - } - - function _encodedDataForDepositOnMakerVault( - uint256 _vaultId, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectMaker.deposit.selector, - _vaultId, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForDepositOnCompound( - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectCompound.deposit.selector, - _token, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForBorrowDaiOnMakerVault( - uint256 _vaultId, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectMaker.borrow.selector, - _vaultId, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForBorrowDaiOnCompound( - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectCompound.borrow.selector, - _token, - _amt, - _getId, - _setId - ); - } - - function _encodeDataForPayingProvider( - address _provider, - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectGelatoProviderPayment.payProvider.selector, - _provider, - _token, - _amt, - _getId, - _setId - ); - } - - function _encodeDataForPayingBackDyDx( - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IFlashLoan.flashPayback.selector, - _token, - _amt, - _getId, - _setId - ); - } - - function _getGelatoProviderFees() - internal - view - virtual - returns (uint256 gasCost) - { - gasCost = mul(GAS_COST, _getGelatoGasPrice()); - } -} diff --git a/contracts/gelato/DebtBridgeFromMakerForPartialRefinance.sol b/contracts/gelato/DebtBridgeFromMakerForPartialRefinance.sol deleted file mode 100644 index b040d5b..0000000 --- a/contracts/gelato/DebtBridgeFromMakerForPartialRefinance.sol +++ /dev/null @@ -1,654 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.7.4; -pragma experimental ABIEncoderV2; - -import {DebtRefinanceMath} from "../lib/DebtRefinanceMath.sol"; -import {IGelatoTaskGenerator} from "../interfaces/IGelatoTaskGenerator.sol"; -import {IConnectMaker} from "../interfaces/IConnectMaker.sol"; -import {IConnectCompound} from "../interfaces/IConnectCompound.sol"; -import {IGelatoGasPriceOracle} from "../interfaces/IGelatoGasPriceOracle.sol"; -import {IFlashLoan} from "../interfaces/IFlashLoan.sol"; -import {DSAInterface} from "../interfaces/DSAInterface.sol"; -import { - IConnectGelatoProviderPayment -} from "../interfaces/IConnectGelatoProviderPayment.sol"; -import {IManager} from "../interfaces/IManager.sol"; -import {IVat} from "../interfaces/IVat.sol"; -import {GelatoBytes} from "../lib/GelatoBytes.sol"; -import {sub, mul, wmul, RAY} from "../vendor/DSMath.sol"; - -abstract contract Helpers { - /** - * @dev Return Maker Connector address. - */ - function _getConnectMaker() internal pure returns (address) { - return 0xac02030d8a8F49eD04b2f52C394D3F901A10F8A9; - } - - /** - * @dev Return Compound Connector address. - */ - function _getConnectCompound() internal pure returns (address) { - return 0x07F81230d73a78f63F0c2A3403AD281b067d28F8; - } - - /** - * @dev Return Default Ether address. - */ - function _getEthAddr() internal pure returns (address) { - return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; - } - - /** - * @dev Return Default Ether address. - */ - function _getDaiTokenAddr() internal pure returns (address) { - return 0x6B175474E89094C44Da98b954EedeAC495271d0F; - } - - /** - * @dev Return Insta pool V2 connector. - */ - function _getInstaPoolV2Addr() internal pure returns (address) { - return 0x3150e5A805577366816A1ddc7330c6Ea17070c05; - } - - /** - * @dev Return Maker MCD Manager address. - */ - function _getMcdManager() internal pure returns (address) { - return 0x5ef30b9986345249bc32d8928B7ee64DE9435E39; - } -} - -abstract contract GelatoHelpers is Helpers { - // To retrieve when the connector is deployed and replace with the address of the deployed instance - address public gelatoPaymentConnectorAddr; - - /** - * @dev Return Gelato Payment Connector. - */ - function _getConnectGelatoProviderPaymentAddr() - internal - view - returns (address) - { - return gelatoPaymentConnectorAddr; - } - - /** - * @dev Return Gelato gas price oracle. - */ - function _getGelatoGasPriceOracle() internal pure returns (address) { - return 0x169E633A2D1E6c10dD91238Ba11c4A708dfEF37C; - } - - /** - * @dev Return Gas price. - */ - function _getGelatoGasPrice() internal view returns (uint256) { - return - uint256( - IGelatoGasPriceOracle(_getGelatoGasPriceOracle()).latestAnswer() - ); - } -} - -abstract contract MakerResolver is GelatoHelpers, DebtRefinanceMath { - /** - * @dev Return Debt in wad of the vault associated to the vaultId. - */ - function getMakerVaultDebt(uint256 _vaultId) - public - view - returns (uint256 wad) - { - IManager cdpManager = _getManager(); - - (bytes32 ilk, address urn) = _getVaultData(cdpManager, _vaultId); - IVat vat = IVat(cdpManager.vat()); - (, uint256 rate, , , ) = vat.ilks(ilk); - (, uint256 art) = vat.urns(ilk, urn); - uint256 dai = vat.dai(urn); - - uint256 rad = sub(mul(art, rate), dai); - wad = rad / RAY; - - wad = mul(wad, RAY) < rad ? wad + 1 : wad; - } - - /** - * @dev Return Collateral in wad of the vault associated to the vaultId. - */ - function getMakerVaultCollateralBalance(uint256 _vaultId) - public - view - returns (uint256) - { - IManager cdpManager = _getManager(); - - IVat vat = IVat(cdpManager.vat()); - (bytes32 ilk, address urn) = _getVaultData(cdpManager, _vaultId); - (uint256 ink, ) = vat.urns(ilk, urn); - - return ink; - } - - function _getVaultData(IManager cdpManager, uint256 vault) - internal - view - returns (bytes32 ilk, address urn) - { - ilk = cdpManager.ilks(vault); - urn = cdpManager.urns(vault); - } - - function _getManager() internal pure returns (IManager) { - return IManager(_getMcdManager()); - } -} - -abstract contract DebtBridgeFromMakerForPartialRefinanceResolver is - MakerResolver -{ - struct PartialDebtBridgePayload { - uint256 vaultId; - address token; - uint256 wMinColRatioMaker; - uint256 wMinColRatioB; - address priceOracle; - bytes oraclePayload; - address provider; - } - - function execPayloadForPartialRefinanceFromMakerToMaker( - PartialDebtBridgePayload memory _payload, - string memory _colType - ) public view virtual returns (address, bytes memory); - - function execPayloadForPartialRefinanceFromMakerToCompound( - PartialDebtBridgePayload memory _payload - ) public view virtual returns (address, bytes memory); - - /// @notice Generate Data for calling execPayloadForPartialRefinanceFromMakerToMaker via a static call. - /// @param _vaultId Id of the unsafe vault of the client. - /// @param _token vault's col token address . - /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position - /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) - /// @param _priceOracle The price oracle contract to supply the collateral price - /// e.g. Maker's ETH/USD oracle for ETH collateral pricing. - /// @param _oraclePayload The data for making the staticcall to the oracle's read - /// method e.g. the function selector of MakerOracle's read function. - /// @param _colType colType of the new vault, exemple : ETH-B, ETH-A. - /// @param _provider address of the paying provider. - /// @return a call data for a static call of execPayloadForPartialRefinanceFromMakerToMaker. - function getDebtBridgePartialRefinanceMakerToMakerData( - uint256 _vaultId, - address _token, - uint256 _wMinColRatioMaker, - uint256 _wMinColRatioB, - address _priceOracle, - bytes calldata _oraclePayload, - string memory _colType, - address _provider - ) public pure returns (bytes memory) { - return - abi.encodeWithSelector( - this.execPayloadForPartialRefinanceFromMakerToMaker.selector, - PartialDebtBridgePayload({ - vaultId: _vaultId, - token: _token, - wMinColRatioMaker: _wMinColRatioMaker, - wMinColRatioB: _wMinColRatioB, - priceOracle: _priceOracle, - oraclePayload: _oraclePayload, - provider: _provider - }), - _colType - ); - } - - /// @notice Generate Data for calling execPayloadForPartialRefinanceFromMakerToCompound via a static call. - /// @param _vaultId Id of the unsafe vault of the client. - /// @param _token vault's col token address . - /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position - /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) - /// @param _priceOracle The price oracle contract to supply the collateral price - /// e.g. Maker's ETH/USD oracle for ETH collateral pricing. - /// @param _oraclePayload The data for making the staticcall to the oracle's read - /// method e.g. the function selector of MakerOracle's read function. - /// @param _provider address of the paying provider. - /// @return a call data for a static call of execPayloadForPartialRefinanceFromMakerToMaker. - function getDebtBridgePartialRefinanceMakerToCompoundData( - uint256 _vaultId, - address _token, - uint256 _wMinColRatioMaker, - uint256 _wMinColRatioB, - address _priceOracle, - bytes calldata _oraclePayload, - address _provider - ) public pure returns (bytes memory) { - return - abi.encodeWithSelector( - this.execPayloadForPartialRefinanceFromMakerToCompound.selector, - PartialDebtBridgePayload({ - vaultId: _vaultId, - token: _token, - wMinColRatioMaker: _wMinColRatioMaker, - wMinColRatioB: _wMinColRatioB, - priceOracle: _priceOracle, - oraclePayload: _oraclePayload, - provider: _provider - }) - ); - } -} - -/// @title DebtBridgeFromMakerForPartialRefinance -/// @notice Task Generator contract that generate task for a full refinancing from maker protocol to another protocol (can be Maker). -/// @author Gelato Team -contract DebtBridgeFromMakerForPartialRefinance is - DebtBridgeFromMakerForPartialRefinanceResolver -{ - using GelatoBytes for bytes; - uint256 public constant GAS_COST = 1490779 + (14908 * 2); // 1933080 + ~2% (Estimated Value) - - constructor(address _gelatoPaymentConnectorAddr) { - gelatoPaymentConnectorAddr = _gelatoPaymentConnectorAddr; - } - - /// @notice Generate Task for a full refinancing between Maker to Compound. - /// @param _payload contain : - // @param _vaultId Id of the unsafe vault of the client. - // @param _token vault's col token address . - // @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position - // @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) - // @param _priceOracle The price oracle contract to supply the collateral price - // e.g. Maker's ETH/USD oracle for ETH collateral pricing. - // @param _oraclePayload The data for making the staticcall to the oracle's read - // method e.g. the function selector of MakerOracle's read function. - // @param _provider address of the paying provider. - /// @return a target the flashloan contract address and the corresponding call data. - function execPayloadForPartialRefinanceFromMakerToCompound( - PartialDebtBridgePayload calldata _payload - ) public view override returns (address, bytes memory) { - address target = _getInstaPoolV2Addr(); - address connectMaker = _getConnectMaker(); - address connectCompound = _getConnectCompound(); - address daiToken = _getDaiTokenAddr(); - - ( - uint256 wDaiDebtToMove, - uint256 wColToWithdrawFromMaker, - uint256 gasFeesPaidFromCol - ) = computeDebtBridge( - _payload.vaultId, - _payload.wMinColRatioMaker, - _payload.wMinColRatioB, - _payload.priceOracle, - _payload.oraclePayload - ); - - address[] memory targets = new address[](6); - targets[0] = connectMaker; // payback - targets[1] = connectMaker; // withdraw - targets[2] = connectCompound; // deposit - targets[3] = connectCompound; // borrow - targets[4] = _getConnectGelatoProviderPaymentAddr(); - targets[5] = target; - - bytes[] memory datas = new bytes[](6); - datas[0] = _encodedDataForPayBackMakerVault( - _payload.vaultId, - uint256(-1), - 0, - 0 - ); - datas[1] = _encodedDataForWithdrawMakerVault( - _payload.vaultId, - uint256(-1), - 0, - 0 - ); - datas[2] = _encodedDataForDepositOnCompound( - _payload.token, - sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), - 0, - 0 - ); - datas[3] = _encodedDataForBorrowDaiOnCompound( - daiToken, - wDaiDebtToMove, - 0, - 0 - ); - datas[4] = _encodeDataForPayingProvider( - _payload.provider, - _payload.token, - gasFeesPaidFromCol, - 0, - 0 - ); - datas[5] = _encodeDataForPayingBackDyDx(daiToken, wDaiDebtToMove, 0, 0); - - bytes memory flashloanCallData = abi.encode(targets, datas); - bytes memory callData = abi.encodeWithSelector( - IFlashLoan.flashBorrowAndCast.selector, - daiToken, - wDaiDebtToMove, - 0, - flashloanCallData - ); - - return (target, callData); - } - - /// @notice Generate Task for a full refinancing between Maker (exemple : ETH-A) to Maker (exemple: ETH-B). - /// @param _payload contain : - // @param _vaultId Id of the unsafe vault of the client. - // @param _token vault's col token address . - // @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position - // @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) - // @param _priceOracle The price oracle contract to supply the collateral price - // e.g. Maker's ETH/USD oracle for ETH collateral pricing. - // @param _oraclePayload The data for making the staticcall to the oracle's read - // method e.g. the function selector of MakerOracle's read function. - // @param _provider address of the paying provider. - /// @param _colType colType of the new vault, exemple : ETH-B, ETH-A. - /// @return a target the flashloan contract address and the corresponding call data. - function execPayloadForPartialRefinanceFromMakerToMaker( - PartialDebtBridgePayload calldata _payload, - string memory _colType - ) public view override returns (address, bytes memory) { - address target = _getInstaPoolV2Addr(); - address connectMaker = _getConnectMaker(); - address daiToken = _getDaiTokenAddr(); - - ( - uint256 wDaiDebtToMove, - uint256 wColToWithdrawFromMaker, - uint256 gasFeesPaidFromCol - ) = computeDebtBridge( - _payload.vaultId, - _payload.wMinColRatioMaker, - _payload.wMinColRatioB, - _payload.priceOracle, - _payload.oraclePayload - ); - - address[] memory targets = new address[](7); - targets[0] = connectMaker; // payback - targets[1] = connectMaker; // withdraw - targets[2] = connectMaker; // open ETH-B vault - targets[3] = connectMaker; // deposit - targets[4] = connectMaker; // borrow - targets[5] = _getConnectGelatoProviderPaymentAddr(); - targets[6] = target; - - bytes[] memory datas = new bytes[](7); - datas[0] = _encodedDataForPayBackMakerVault( - _payload.vaultId, - uint256(-1), - 0, - 0 - ); - datas[1] = _encodedDataForWithdrawMakerVault( - _payload.vaultId, - uint256(-1), - 0, - 0 - ); - datas[2] = _encodedDataForOpenAMakerVault(_colType); - datas[3] = _encodedDataForDepositOnMakerVault( - 0, - sub(wColToWithdrawFromMaker, gasFeesPaidFromCol), - 0, - 0 - ); - datas[4] = _encodedDataForBorrowDaiOnMakerVault( - 0, - wDaiDebtToMove, - 0, - 0 - ); - datas[5] = _encodeDataForPayingProvider( - _payload.provider, - _payload.token, - gasFeesPaidFromCol, - 0, - 0 - ); - datas[6] = _encodeDataForPayingBackDyDx(daiToken, wDaiDebtToMove, 0, 0); - - bytes memory flashloanCallData = abi.encode(targets, datas); - bytes memory callData = abi.encodeWithSelector( - IFlashLoan.flashBorrowAndCast.selector, - daiToken, - wDaiDebtToMove, - 0, - flashloanCallData - ); - - return (target, callData); - } - - /// @notice Computes values needed for DebtBridge Maker->ProtocolB - /// @dev Use wad for colRatios. - /// @param _vaultId The id of the makerDAO vault. - /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position - /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) - /// @param _priceOracle The price oracle contract to supply the collateral price - /// e.g. Maker's ETH/USD oracle for ETH collateral pricing. - /// @param _oraclePayload The data for making the staticcall to the oracle's read - /// method e.g. the function selector of MakerOracle's read function. - /// @return wDaiDebtToMove DAI Debt (wad) to: flashBorrow->repay Maker->withdraw from B->flashPayback. - /// @return wColToWithdrawFromMaker (wad) to: withdraw from Maker and deposit on B. - /// @return gasFeesPaidFromCol Gelato automation-gas-fees paid from user's collateral - // solhint-disable function-max-lines - function computeDebtBridge( - uint256 _vaultId, - uint256 _wMinColRatioMaker, - uint256 _wMinColRatioB, - address _priceOracle, - bytes calldata _oraclePayload - ) - public - view - virtual - returns ( - uint256 wDaiDebtToMove, - uint256 wColToWithdrawFromMaker, - uint256 gasFeesPaidFromCol - ) - { - uint256 wColPrice; - - // Stack too deep - { - (bool success, bytes memory returndata) = _priceOracle.staticcall( - _oraclePayload - ); - - if (!success) { - returndata.revertWithErrorString( - "ConnectGelatoPartialDebtBridgeFromMaker.computeDebtBridge:oracle:" - ); - } - - wColPrice = abi.decode(returndata, (uint256)); - } - - // TO DO: add fee mechanism for non-ETH collateral debt bridge - // uint256 gasFeesPaidFromCol = _mul(GAS_COST, wmul(_getGelatoGasPrice(), latestPrice)); - gasFeesPaidFromCol = _getGelatoProviderFees(); - - uint256 wPricedCol = wmul( - sub(getMakerVaultCollateralBalance(_vaultId), gasFeesPaidFromCol), - wColPrice - ); - - uint256 wDaiDebtOnMaker = getMakerVaultDebt(_vaultId); - - wColToWithdrawFromMaker = wCalcCollateralToWithdraw( - _wMinColRatioMaker, - _wMinColRatioB, - wColPrice, - wPricedCol, - wDaiDebtOnMaker - ); - - wDaiDebtToMove = wCalcDebtToRepay( - _wMinColRatioMaker, - _wMinColRatioB, - wPricedCol, - wDaiDebtOnMaker - ); - } - - function _encodedDataForPayBackMakerVault( - uint256 _vaultId, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectMaker.payback.selector, - _vaultId, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForWithdrawMakerVault( - uint256 _vaultId, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectMaker.withdraw.selector, - _vaultId, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForOpenAMakerVault(string memory _colType) - internal - pure - returns (bytes memory) - { - return abi.encodeWithSelector(IConnectMaker.open.selector, _colType); - } - - function _encodedDataForDepositOnMakerVault( - uint256 _vaultId, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectMaker.deposit.selector, - _vaultId, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForDepositOnCompound( - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectCompound.deposit.selector, - _token, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForBorrowDaiOnMakerVault( - uint256 _vaultId, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectMaker.borrow.selector, - _vaultId, - _amt, - _getId, - _setId - ); - } - - function _encodedDataForBorrowDaiOnCompound( - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectCompound.borrow.selector, - _token, - _amt, - _getId, - _setId - ); - } - - function _encodeDataForPayingProvider( - address _provider, - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IConnectGelatoProviderPayment.payProvider.selector, - _provider, - _token, - _amt, - _getId, - _setId - ); - } - - function _encodeDataForPayingBackDyDx( - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) internal pure returns (bytes memory) { - return - abi.encodeWithSelector( - IFlashLoan.flashPayback.selector, - _token, - _amt, - _getId, - _setId - ); - } - - function _getGelatoProviderFees() - internal - view - virtual - returns (uint256 gasCost) - { - gasCost = mul(GAS_COST, _getGelatoGasPrice()); - } -} diff --git a/contracts/interfaces/DSAInterface.sol b/contracts/interfaces/DSAInterface.sol deleted file mode 100644 index cc1eb1f..0000000 --- a/contracts/interfaces/DSAInterface.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.7.4; -pragma experimental ABIEncoderV2; - -interface DSAInterface { - function cast( - address[] calldata _targets, - bytes[] calldata _datas, - address _origin - ) external payable; -} diff --git a/contracts/interfaces/IGelatoTaskGenerator.sol b/contracts/interfaces/IGelatoTaskGenerator.sol deleted file mode 100644 index cc415de..0000000 --- a/contracts/interfaces/IGelatoTaskGenerator.sol +++ /dev/null @@ -1,7 +0,0 @@ -// "SPDX-License-Identifier: UNLICENSED" -pragma solidity 0.7.4; - -interface IGelatoTaskGenerator { - // solhint-disable-next-line func-name-mixedcase - function SELECTOR() external pure returns (bytes4); -} diff --git a/contracts/interfaces/IMakerPriceFeed.sol b/contracts/interfaces/IMakerPriceFeed.sol deleted file mode 100644 index f3580af..0000000 --- a/contracts/interfaces/IMakerPriceFeed.sol +++ /dev/null @@ -1,6 +0,0 @@ -// "SPDX-License-Identifier: UNLICENSED" -pragma solidity 0.7.4; - -interface IMakerPriceFeed { - function read() external view returns (bytes32); -} diff --git a/contracts/interfaces/InstaDapp.sol b/contracts/interfaces/InstaDapp/IInstaDapp.sol similarity index 86% rename from contracts/interfaces/InstaDapp.sol rename to contracts/interfaces/InstaDapp/IInstaDapp.sol index eda8df3..5fe36ac 100644 --- a/contracts/interfaces/InstaDapp.sol +++ b/contracts/interfaces/InstaDapp/IInstaDapp.sol @@ -35,3 +35,9 @@ interface AccountInterface { function shield() external view returns (bool); } + +interface ConnectorInterface { + function connectorID() external view returns (uint256 _type, uint256 _id); + + function name() external view returns (string memory); +} diff --git a/contracts/interfaces/IConnectCompound.sol b/contracts/interfaces/InstaDapp/connectors/IConnectCompound.sol similarity index 100% rename from contracts/interfaces/IConnectCompound.sol rename to contracts/interfaces/InstaDapp/connectors/IConnectCompound.sol diff --git a/contracts/interfaces/IConnectGelatoProviderPayment.sol b/contracts/interfaces/InstaDapp/connectors/IConnectGelatoProviderPayment.sol similarity index 100% rename from contracts/interfaces/IConnectGelatoProviderPayment.sol rename to contracts/interfaces/InstaDapp/connectors/IConnectGelatoProviderPayment.sol diff --git a/contracts/interfaces/IFlashLoan.sol b/contracts/interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol similarity index 91% rename from contracts/interfaces/IFlashLoan.sol rename to contracts/interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol index 483e219..9a861bb 100644 --- a/contracts/interfaces/IFlashLoan.sol +++ b/contracts/interfaces/InstaDapp/connectors/IConnectInstaPoolV2.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.7.4; -interface IFlashLoan { +interface IConnectInstaPoolV2 { function flashBorrowAndCast( address token, uint256 amt, diff --git a/contracts/interfaces/IConnectMaker.sol b/contracts/interfaces/InstaDapp/connectors/IConnectMaker.sol similarity index 100% rename from contracts/interfaces/IConnectMaker.sol rename to contracts/interfaces/InstaDapp/connectors/IConnectMaker.sol diff --git a/contracts/interfaces/IInstaMakerResolver.sol b/contracts/interfaces/InstaDapp/resolvers/IInstaMakerResolver.sol similarity index 100% rename from contracts/interfaces/IInstaMakerResolver.sol rename to contracts/interfaces/InstaDapp/resolvers/IInstaMakerResolver.sol diff --git a/contracts/interfaces/IManager.sol b/contracts/interfaces/Maker/IManager.sol similarity index 100% rename from contracts/interfaces/IManager.sol rename to contracts/interfaces/Maker/IManager.sol diff --git a/contracts/interfaces/IVat.sol b/contracts/interfaces/Maker/IVat.sol similarity index 100% rename from contracts/interfaces/IVat.sol rename to contracts/interfaces/Maker/IVat.sol diff --git a/contracts/interfaces/IGelatoGasPriceOracle.sol b/contracts/interfaces/gelato/IGelatoGasPriceOracle.sol similarity index 100% rename from contracts/interfaces/IGelatoGasPriceOracle.sol rename to contracts/interfaces/gelato/IGelatoGasPriceOracle.sol diff --git a/contracts/interfaces/tokens/IERC20.sol b/contracts/interfaces/tokens/IERC20.sol new file mode 100644 index 0000000..a907394 --- /dev/null +++ b/contracts/interfaces/tokens/IERC20.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.4; + +interface IERC20 { + function transfer(address recipient, uint256 amount) + external + returns (bool); +} diff --git a/contracts/lib/DebtRefinanceMath.sol b/contracts/lib/DebtRefinanceMath.sol deleted file mode 100644 index a92b37d..0000000 --- a/contracts/lib/DebtRefinanceMath.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.7.4; - -import {sub, wmul, wdiv} from "../vendor/DSMath.sol"; - -/* solhint-disable */ - -contract DebtRefinanceMath { - /// @notice Compute collateral (wad) to move from Maker to B. - /// @dev TO DO: explain or link to formula paper. - /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position - /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) - /// @param _wColPrice Price of the collateral (wad) in oracle price units. - /// @param _wPricedCol Collateral to move (wad) valued in oracle price. - /// @param _wDaiDebtOnMaker Amount of DAI (wad) borrowed from Maker. - /// @return collateral to withdraw from A in wad - function wCalcCollateralToWithdraw( - uint256 _wMinColRatioMaker, - uint256 _wMinColRatioB, - uint256 _wColPrice, - uint256 _wPricedCol, - uint256 _wDaiDebtOnMaker - ) public pure virtual returns (uint256) { - return - wdiv( - sub( - _wPricedCol, - wdiv( - sub( - wmul(_wMinColRatioMaker, _wPricedCol), - wmul( - _wMinColRatioMaker, - wmul(_wMinColRatioB, _wDaiDebtOnMaker) - ) - ), - sub(_wMinColRatioMaker, _wMinColRatioB) - ) - ), - _wColPrice - ); - } - - /// @notice Compute debt (wad) to flashBorrow->repay Maker->withdraw from B->flashPayback - /// @dev TO DO: explain or link to formula paper. - /// @param _wMinColRatioMaker Min col ratio (wad) on Maker debt position - /// @param _wMinColRatioB Min col ratio (wad) on debt position B (e.g. Compound, Maker, ...) - /// @param _wPricedCol Collateral to move (wad) valued in oracle price. - /// @param _wDaiDebtOnMaker Amount of DAI (wad) borrowed from Maker. - /// @return amount of borrowed token to pay back in wad - function wCalcDebtToRepay( - uint256 _wMinColRatioMaker, - uint256 _wMinColRatioB, - uint256 _wPricedCol, - uint256 _wDaiDebtOnMaker - ) public pure virtual returns (uint256) { - return - sub( - _wDaiDebtOnMaker, - wmul( - wdiv(1e18, _wMinColRatioMaker), - wdiv( - sub( - wmul(_wMinColRatioMaker, _wPricedCol), - wmul( - _wMinColRatioMaker, - wmul(_wMinColRatioB, _wDaiDebtOnMaker) - ) - ), - sub(_wMinColRatioMaker, _wMinColRatioB) - ) - ) - ); - } -} diff --git a/contracts/lib/GelatoBytes.sol b/contracts/lib/GelatoBytes.sol index 71a60bc..7af80f7 100644 --- a/contracts/lib/GelatoBytes.sol +++ b/contracts/lib/GelatoBytes.sol @@ -26,10 +26,10 @@ library GelatoBytes { (bytes4(_bytes[3]) >> 24); } - function revertWithErrorString( - bytes memory _bytes, - string memory _tracingInfo - ) internal pure { + function revertWithError(bytes memory _bytes, string memory _tracingInfo) + internal + pure + { // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err if (_bytes.length % 32 == 4) { bytes4 selector; @@ -54,10 +54,11 @@ library GelatoBytes { } } - function generateErrorString( - bytes memory _bytes, - string memory _tracingInfo - ) internal pure returns (string memory) { + function returnError(bytes memory _bytes, string memory _tracingInfo) + internal + pure + returns (string memory) + { // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err if (_bytes.length % 32 == 4) { bytes4 selector; diff --git a/contracts/lib/GelatoString.sol b/contracts/lib/GelatoString.sol new file mode 100644 index 0000000..bb6c7ba --- /dev/null +++ b/contracts/lib/GelatoString.sol @@ -0,0 +1,28 @@ +// "SPDX-License-Identifier: UNLICENSED" +pragma solidity 0.7.4; + +library GelatoString { + function startsWithOK(string memory _str) internal pure returns (bool) { + if ( + bytes(_str).length >= 2 && + bytes(_str)[0] == "O" && + bytes(_str)[1] == "K" + ) return true; + return false; + } + + function revertWithInfo(string memory _error, string memory _tracingInfo) + internal + pure + { + revert(string(abi.encodePacked(_tracingInfo, _error))); + } + + function returnWithInfo(string memory _error, string memory _tracingInfo) + internal + pure + returns (string memory) + { + return string(abi.encodePacked(_tracingInfo, _error)); + } +} diff --git a/contracts/resolvers/GelatoTaskResolver.sol b/contracts/resolvers/GelatoTaskResolver.sol deleted file mode 100644 index f4e7f91..0000000 --- a/contracts/resolvers/GelatoTaskResolver.sol +++ /dev/null @@ -1,62 +0,0 @@ -// "SPDX-License-Identifier: UNLICENSED" -pragma solidity 0.7.4; -pragma experimental ABIEncoderV2; - -import {Ownable} from "../vendor/Ownable.sol"; -import {GelatoBytes} from "../lib/GelatoBytes.sol"; -import {IGelatoTaskGenerator} from "../interfaces/IGelatoTaskGenerator.sol"; -import { - Task -} from "@gelatonetwork/core/contracts/gelato_core/interfaces/IGelatoCore.sol"; - -/// @title GelatoTaskResolver -/// @notice Convenience contract with methods to retrieve Task objects from Task Generators. -/// @dev Can be used by Frontends and Maintainers to: -/// - Frontends: Retrieve Task structs from Task Generators for submission to GelatoCore -/// - Maintainer: Add new version of Task Generators -contract GelatoTaskResolver is Ownable { - using GelatoBytes for bytes; - - /// @notice The contract that has the function returning a Task object - mapping(string => IGelatoTaskGenerator) public taskGenerator; - - /// @notice Adds a new TaskGenerator address - /// @dev Only owner can call this, but existing taskGenerator entries are immutable - /// @param _taskGenerator The descriptor of the taskGenerator e.g. GelatoDebtBridgeFromMaker - /// @param _taskGeneratorAddr The address of the taskGenerator contract - function addTaskGenerator( - string memory _taskGenerator, - IGelatoTaskGenerator _taskGeneratorAddr - ) external onlyOwner { - require( - taskGenerator[_taskGenerator] == IGelatoTaskGenerator(0), - "GelatoTaskResolver.addTaskGenerator: set" - ); - taskGenerator[_taskGenerator] = _taskGeneratorAddr; - } - - /// @notice A generelized getter for a price supplied by an taskGenerator contract. - /// @dev The taskGenerator returndata must be formatted as a single uint256. - /// @param _taskGenerator The descriptor of our taskGenerator e.g. ETH/USD-Maker-v1 - /// @return The uint256 taskGenerator price - function getTask( - string calldata _taskGenerator, - bytes calldata _abiEncodedParams - ) external view returns (Task memory) { - address taskGeneratorAddr = address(taskGenerator[_taskGenerator]); - - if (taskGeneratorAddr == address(0)) - revert("GelatoTaskResolver.getTask: !taskGenerator"); - - (bool success, bytes memory returndata) = taskGeneratorAddr.staticcall( - abi.encodePacked( - taskGenerator[_taskGenerator].SELECTOR(), - _abiEncodedParams - ) - ); - - if (!success) - returndata.revertWithErrorString("GelatoTaskResolver.getTask:"); - return abi.decode(returndata, (Task)); - } -} diff --git a/contracts/connectors/ConnectGelatoProviderPayment.sol b/contracts/vendor/Address.sol similarity index 54% rename from contracts/connectors/ConnectGelatoProviderPayment.sol rename to contracts/vendor/Address.sol index 114911d..0ed6b65 100644 --- a/contracts/connectors/ConnectGelatoProviderPayment.sol +++ b/contracts/vendor/Address.sol @@ -1,26 +1,6 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.7.4; -/* solhint-disable */ - -interface MemoryInterface { - function setUint(uint256 _id, uint256 _val) external; - - function getUint(uint256 _id) external returns (uint256); -} - -interface ConnectorInterface { - function connectorID() external view returns (uint256 _type, uint256 _id); - - function name() external view returns (string memory); -} - -interface IERC20 { - function transfer(address recipient, uint256 amount) - external - returns (bool); -} - library Address { /** * @dev Returns true if `account` is a contract. @@ -193,142 +173,4 @@ library Address { } } } -} - -library SafeERC20 { - using Address for address; - - function safeTransfer( - IERC20 token, - address to, - uint256 value - ) internal { - _callOptionalReturn( - token, - abi.encodeWithSelector(token.transfer.selector, to, value) - ); - } - - /** - * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement - * on the return value: the return value is optional (but if data is returned, it must not be false). - * @param token The token targeted by the call. - * @param data The call data (encoded using abi.encode or one of its variants). - */ - function _callOptionalReturn(IERC20 token, bytes memory data) private { - // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since - // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that - // the target address contains contract code and also asserts for success in the low-level call. - - bytes memory returndata = address(token).functionCall( - data, - "SafeERC20: low-level call failed" - ); - if (returndata.length > 0) { - // Return data is optional - // solhint-disable-next-line max-line-length - require( - abi.decode(returndata, (bool)), - "SafeERC20: ERC20 operation did not succeed" - ); - } - } -} - -/* solhint-enable */ - -/* solhint-disable private-vars-leading-underscore */ - -abstract contract Helpers is ConnectorInterface { - uint256 internal __id; - - /** - * @dev Connector Details - */ - function connectorID() - public - view - override - returns (uint256 _type, uint256 id) - { - (_type, id) = (1, __id); // Should put specific value. - } - - /** - * @dev Return ethereum address - */ - function getAddressETH() internal pure returns (address) { - return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // ETH Address - } - - /** - * @dev Return Memory Variable Address - */ - function getMemoryAddr() internal pure returns (address) { - return 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; // InstaMemory Address - } - - /** - * @dev Set Uint value in InstaMemory Contract. - */ - function setUint(uint256 setId, uint256 val) internal { - if (setId != 0) MemoryInterface(getMemoryAddr()).setUint(setId, val); - } - - /** - * @dev Get Uint value from InstaMemory Contract. - */ - function getUint(uint256 getId, uint256 val) - internal - returns (uint256 returnVal) - { - returnVal = getId == 0 - ? val - : MemoryInterface(getMemoryAddr()).getUint(getId); - } -} - -/// @title ConnectGelatoProviderPayment -/// @notice InstaDapp Connector to compensate Gelato automation-gas Providers. -/// @author Gelato Team -contract ConnectGelatoProviderPayment is Helpers { - using Address for address payable; - using SafeERC20 for IERC20; - - // solhint-disable-next-line const-name-snakecase - string public constant override name = "GelatoProviderPayement-v1.0"; - - constructor(uint256 _id) { - __id = _id; - } - - /// @notice Transfers automation gas fees to Gelato Provider - /// @dev Gelato Provider risks: - /// - _getId does not match actual InstaMemory provider payment slot - /// - _token balance not in DSA - /// - worthless _token risk - /// @param _provider The Provider who pays the Gelato network for automation. - // This param should be verified / replaced by the ProviderModule in Gelato on-chain. - // In the latter case, it does not matter what address is passed off-chain. - /// @param _token The token used to pay the Provider. - /// @param _amt The amount of _token to pay the Gelato Provider. - /// @param _getId The InstaMemory slot at which the payment amount was stored. - /// @param _setId The InstaMemory slot to save the provider payout amound in. - function payProvider( - address _provider, - address _token, - uint256 _amt, - uint256 _getId, - uint256 _setId - ) public payable virtual { - require( - _provider != address(0x0), - "ConnectGelatoProviderPayment.payProvider:addr0" - ); - uint256 amt = getUint(_getId, _amt); - setUint(_setId, amt); - _token == getAddressETH() - ? payable(_provider).sendValue(amt) - : IERC20(_token).safeTransfer(_provider, amt); - } -} +} \ No newline at end of file diff --git a/contracts/vendor/Ownable.sol b/contracts/vendor/Ownable.sol index b068637..f642c63 100644 --- a/contracts/vendor/Ownable.sol +++ b/contracts/vendor/Ownable.sol @@ -1,4 +1,4 @@ -// "SPDX-License-Identifier: UNLICENSED" +// "SPDX-License-Identifier: MIT" pragma solidity 0.7.4; /** diff --git a/contracts/vendor/SafeERC20.sol b/contracts/vendor/SafeERC20.sol new file mode 100644 index 0000000..550b99e --- /dev/null +++ b/contracts/vendor/SafeERC20.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.4; + +import {Address} from "./Address.sol"; +import {IERC20} from "../interfaces/tokens/IERC20.sol"; + +library SafeERC20 { + using Address for address; + + function safeTransfer( + IERC20 token, + address to, + uint256 value + ) internal { + _callOptionalReturn( + token, + abi.encodeWithSelector(token.transfer.selector, to, value) + ); + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(IERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that + // the target address contains contract code and also asserts for success in the low-level call. + + bytes memory returndata = address(token).functionCall( + data, + "SafeERC20: low-level call failed" + ); + if (returndata.length > 0) { + // Return data is optional + // solhint-disable-next-line max-line-length + require( + abi.decode(returndata, (bool)), + "SafeERC20: ERC20 operation did not succeed" + ); + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index 8135bb7..d280e5f 100644 --- a/package.json +++ b/package.json @@ -22,15 +22,15 @@ "chai": "4.2.0", "dotenv": "8.2.0", "eslint": "7.12.1", - "eslint-config-prettier": "6.14.0", - "ethereum-waffle": "3.1.2", + "eslint-config-prettier": "6.15.0", + "ethereum-waffle": "3.2.0", "ethers": "5.0.19", "hardhat": "2.0.2", "husky": ">=4", - "lint-staged": "10.5.0", + "lint-staged": "10.5.1", "prettier": "2.1.2", "prettier-plugin-solidity": "1.0.0-alpha.59", - "solhint": "3.3.0", + "solhint": "3.3.1", "solhint-plugin-prettier": "0.0.5" }, "dependencies": {}, diff --git a/test/2_Full-Debt-Bridge-Maker-Compound.test.js b/test/2_Full-Debt-Bridge-Maker-Compound.test.js index 4cde8c5..1a98152 100644 --- a/test/2_Full-Debt-Bridge-Maker-Compound.test.js +++ b/test/2_Full-Debt-Bridge-Maker-Compound.test.js @@ -3,7 +3,7 @@ const hre = require("hardhat"); const {ethers} = hre; const GelatoCoreLib = require("@gelatonetwork/core"); -const makerToCompoundSetup = require("./helpers/Full-Refinance-External-Provider-Maker-To-Compound.helper"); +const makerToCompoundSetup = require("./helpers/Full-Refinance-Maker-To-Compound.helper"); // This test showcases how to submit a task refinancing a Users debt position from // Maker to Compound using Gelato @@ -182,13 +182,11 @@ describe("Full Debt Bridge refinancing loan from Maker to Compound", function () const gasFeesPaidFromCol = ethers.utils .parseUnits(String(1490779 + 14908 * 2), 0) .mul(gelatoGasPrice); - const debtOnMakerBefore = await contracts.debtBridgeFromMaker.getMakerVaultDebt( + const debtOnMakerBefore = await contracts.makerResolver.getMakerVaultDebt( vaultId ); const pricedCollateral = ( - await contracts.debtBridgeFromMaker.getMakerVaultCollateralBalance( - vaultId - ) + await contracts.makerResolver.getMakerVaultCollateralBalance(vaultId) ).sub(gasFeesPaidFromCol); //#endregion @@ -246,10 +244,10 @@ describe("Full Debt Bridge refinancing loan from Maker to Compound", function () ) ).to.be.lt(ethers.utils.parseUnits("1", 12)); - const debtOnMakerAfter = await contracts.debtBridgeFromMaker.getMakerVaultDebt( + const debtOnMakerAfter = await contracts.makerResolver.getMakerVaultDebt( vaultId ); - const collateralOnMakerAfter = await contracts.debtBridgeFromMaker.getMakerVaultCollateralBalance( + const collateralOnMakerAfter = await contracts.makerResolver.getMakerVaultCollateralBalance( vaultId ); // in Ether. @@ -258,9 +256,9 @@ describe("Full Debt Bridge refinancing loan from Maker to Compound", function () expect(collateralOnMakerAfter).to.be.equal(ethers.constants.Zero); // DSA contain 1000 DAI - expect( - await contracts.daiToken.balanceOf(contracts.dsa.address) - ).to.be.equal(constants.MAKER_INITIAL_DEBT); + expect(await contracts.DAI.balanceOf(contracts.dsa.address)).to.be.equal( + constants.MAKER_INITIAL_DEBT + ); //#endregion }); diff --git a/test/3_Full-Debt-Bridge-ETHA-ETHB.test.js b/test/3_Full-Debt-Bridge-ETHA-ETHB.test.js index 264b261..8055b48 100644 --- a/test/3_Full-Debt-Bridge-ETHA-ETHB.test.js +++ b/test/3_Full-Debt-Bridge-ETHA-ETHB.test.js @@ -3,7 +3,7 @@ const hre = require("hardhat"); const {ethers} = hre; const GelatoCoreLib = require("@gelatonetwork/core"); -const makerETHAToMakerETHBSetup = require("./helpers/Full-Refinance-External-Provider-Maker-To-Maker.helper"); +const makerETHAToMakerETHBSetup = require("./helpers/Full-Refinance-Maker-To-Maker.helper"); // This test showcases how to submit a task refinancing a Users debt position from // Maker to Compound using Gelato @@ -187,13 +187,11 @@ describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B", function () { const gasFeesPaidFromCol = ethers.utils .parseUnits(String(1490779 + 14908 * 2), 0) .mul(gelatoGasPrice); - const debtOnMakerBefore = await contracts.debtBridgeFromMaker.getMakerVaultDebt( + const debtOnMakerBefore = await contracts.makerResolver.getMakerVaultDebt( vaultAId ); const pricedCollateral = ( - await contracts.debtBridgeFromMaker.getMakerVaultCollateralBalance( - vaultAId - ) + await contracts.makerResolver.getMakerVaultCollateralBalance(vaultAId) ).sub(gasFeesPaidFromCol); //#endregion @@ -228,10 +226,10 @@ describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B", function () { let vaultBId = String(cdps.ids[1]); expect(cdps.ids[1].isZero()).to.be.false; - const debtOnMakerVaultB = await contracts.debtBridgeFromMaker.getMakerVaultDebt( + const debtOnMakerVaultB = await contracts.makerResolver.getMakerVaultDebt( vaultBId ); - const pricedCollateralOnVaultB = await contracts.debtBridgeFromMaker.getMakerVaultCollateralBalance( + const pricedCollateralOnVaultB = await contracts.makerResolver.getMakerVaultCollateralBalance( vaultBId ); @@ -245,10 +243,10 @@ describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B", function () { // Estimated amount of collateral should be equal to the actual one read on compound contracts expect(pricedCollateral).to.be.equal(pricedCollateralOnVaultB); - const debtOnMakerOnVaultAAfter = await contracts.debtBridgeFromMaker.getMakerVaultDebt( + const debtOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultDebt( vaultAId ); - const collateralOnMakerOnVaultAAfter = await contracts.debtBridgeFromMaker.getMakerVaultCollateralBalance( + const collateralOnMakerOnVaultAAfter = await contracts.makerResolver.getMakerVaultCollateralBalance( vaultAId ); // in Ether. @@ -257,9 +255,9 @@ describe("Full Debt Bridge refinancing loan from ETH-A to ETH-B", function () { expect(collateralOnMakerOnVaultAAfter).to.be.equal(ethers.constants.Zero); // DSA has maximum 2 wei DAI in it due to maths inaccuracies - expect( - await contracts.daiToken.balanceOf(contracts.dsa.address) - ).to.be.equal(constants.MAKER_INITIAL_DEBT); + expect(await contracts.DAI.balanceOf(contracts.dsa.address)).to.be.equal( + constants.MAKER_INITIAL_DEBT + ); //#endregion }); diff --git a/test/helpers/Full-Refinance-External-Provider-Maker-To-Compound.helper.js b/test/helpers/Full-Refinance-Maker-To-Compound.helper.js similarity index 89% rename from test/helpers/Full-Refinance-External-Provider-Maker-To-Compound.helper.js rename to test/helpers/Full-Refinance-Maker-To-Compound.helper.js index ab45849..7ada4ea 100644 --- a/test/helpers/Full-Refinance-External-Provider-Maker-To-Compound.helper.js +++ b/test/helpers/Full-Refinance-Maker-To-Compound.helper.js @@ -15,7 +15,7 @@ const getABI = require("./setups/ABI.helper"); const getAllContracts = require("./setups/Contracts-For-Full-Refinancing-Maker-To-Compound.helper"); const enableGelatoConnectorsForFromMaker = require("./setups/Enabling-New-Connectors-For-Full-Refinance.helper"); -const ConnectGelatoDebtBridgeABI = require("./../../artifacts/contracts/connectors/ConnectGelatoDebtBridge.sol/ConnectGelatoDebtBridge.json") +const ConnectGelatoDataABI = require("../../artifacts/contracts/contracts/connectors/ConnectGelatoData.sol/ConnectGelatoData.json") .abi; async function makerToCompoundSetup() { @@ -27,7 +27,7 @@ async function makerToCompoundSetup() { await enableGelatoConnectorsForFromMaker( wallets.userWallet, contracts.connectGelatoProviderPayment.address, - contracts.connectGelatoDebtBridge.address, + contracts.connectGelatoData.address, contracts.instaMaster, contracts.instaConnectors ); @@ -55,7 +55,7 @@ async function makerToCompoundSetup() { ); vaultId = await userOpenDepositBorrowOnMakerVault( wallets.userAddress, - contracts.daiToken, + contracts.DAI, contracts.dsa, contracts.getCdps, contracts.dssCdpManager, @@ -96,7 +96,7 @@ async function providerWhiteListTaskForMakerToCompound( //#region Actions - const data = await contracts.debtBridgeFromMaker.getDebtBridgeFullRefinanceMakerToCompoundData( + const data = await contracts.debtBridgeFromMakerForFullRefinance.getDebtBridgeFullRefinanceMakerToCompoundData( vaultId, constants.ETH, wallets.providerAddress @@ -105,11 +105,11 @@ async function providerWhiteListTaskForMakerToCompound( const spells = []; const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({ - addr: contracts.connectGelatoDebtBridge.address, + addr: contracts.connectGelatoData.address, data: await hre.run("abi-encode-withselector", { - abi: ConnectGelatoDebtBridgeABI, - functionname: "computeRefinanceDataAndCast", - inputs: [contracts.debtBridgeFromMaker.address, data], + abi: ConnectGelatoDataABI, + functionname: "getDataAndCast", + inputs: [contracts.debtBridgeFromMakerForFullRefinance.address, data], }), operation: GelatoCoreLib.Operation.Delegatecall, }); diff --git a/test/helpers/Full-Refinance-External-Provider-Maker-To-Maker.helper.js b/test/helpers/Full-Refinance-Maker-To-Maker.helper.js similarity index 89% rename from test/helpers/Full-Refinance-External-Provider-Maker-To-Maker.helper.js rename to test/helpers/Full-Refinance-Maker-To-Maker.helper.js index ab59a5b..3efd779 100644 --- a/test/helpers/Full-Refinance-External-Provider-Maker-To-Maker.helper.js +++ b/test/helpers/Full-Refinance-Maker-To-Maker.helper.js @@ -16,7 +16,7 @@ const getABI = require("./setups/ABI.helper"); const getAllContracts = require("./setups/Contracts-For-Full-Refinancing-Maker-To-Maker.helper"); const enableGelatoConnectorsForFromMaker = require("./setups/Enabling-New-Connectors-For-Full-Refinance.helper"); -const ConnectGelatoDebtBridgeABI = require("./../../artifacts/contracts/connectors/ConnectGelatoDebtBridge.sol/ConnectGelatoDebtBridge.json") +const ConnectGelatoDataABI = require("../../artifacts/contracts/contracts/connectors/ConnectGelatoData.sol/ConnectGelatoData.json") .abi; async function makerETHAToMakerETHBSetup() { @@ -28,7 +28,7 @@ async function makerETHAToMakerETHBSetup() { await enableGelatoConnectorsForFromMaker( wallets.userWallet, contracts.connectGelatoProviderPayment.address, - contracts.connectGelatoDebtBridge.address, + contracts.connectGelatoData.address, contracts.instaMaster, contracts.instaConnectors ); @@ -61,7 +61,7 @@ async function makerETHAToMakerETHBSetup() { ); vaultAId = await userOpenDepositBorrowOnMakerVault( wallets.userAddress, - contracts.daiToken, + contracts.DAI, contracts.dsa, contracts.getCdps, contracts.dssCdpManager, @@ -102,7 +102,7 @@ async function providerWhiteListTaskForMakerETHAToMakerETHB( //#region Actions - const data = await contracts.debtBridgeFromMaker.getDebtBridgeFullRefinanceMakerToMakerData( + const data = await contracts.debtBridgeFromMakerForFullRefinance.getDebtBridgeFullRefinanceMakerToMakerData( vaultId, constants.ETH, "ETH-B", @@ -112,11 +112,11 @@ async function providerWhiteListTaskForMakerETHAToMakerETHB( const spells = []; const debtBridgeCalculationForFullRefinance = new GelatoCoreLib.Action({ - addr: contracts.connectGelatoDebtBridge.address, + addr: contracts.connectGelatoData.address, data: await hre.run("abi-encode-withselector", { - abi: ConnectGelatoDebtBridgeABI, - functionname: "computeRefinanceDataAndCast", - inputs: [contracts.debtBridgeFromMaker.address, data], + abi: ConnectGelatoDataABI, + functionname: "getDataAndCast", + inputs: [contracts.debtBridgeFromMakerForFullRefinance.address, data], }), operation: GelatoCoreLib.Operation.Delegatecall, }); diff --git a/test/helpers/setups/ABI.helper.js b/test/helpers/setups/ABI.helper.js index 1f0f2bf..af8bf7a 100644 --- a/test/helpers/setups/ABI.helper.js +++ b/test/helpers/setups/ABI.helper.js @@ -1,6 +1,6 @@ const ConnectGelatoABI = require("./../../../pre-compiles/ConnectGelato.json") .abi; -const PriceOracleResolverABI = require("./../../../artifacts/contracts/resolvers/PriceOracleResolver.sol/PriceOracleResolver.json") +const PriceOracleResolverABI = require("./../../../artifacts/contracts/contracts/resolvers/PriceOracleResolver.sol/PriceOracleResolver.json") .abi; const ConnectAuthABI = require("./../../../pre-compiles/ConnectAuth.json").abi; diff --git a/test/helpers/setups/Common-Contracts.helper.js b/test/helpers/setups/Common-Contracts.helper.js index 14df9a3..7941b15 100644 --- a/test/helpers/setups/Common-Contracts.helper.js +++ b/test/helpers/setups/Common-Contracts.helper.js @@ -27,7 +27,7 @@ async function getContracts() { let instaList; let dssCdpManager; let getCdps; - let daiToken; + let DAI; let gelatoCore; let cDaiToken; let cEthToken; @@ -39,8 +39,8 @@ async function getContracts() { let conditionMakerVaultUnsafe; let connectGelatoProviderPayment; let priceOracleResolver; - let connectGelatoDebtBridge; - let debtBridgeFromMaker; + let connectGelatoData; + let debtBridgeFromMakerForFullRefinance; instaMaster = await ethers.provider.getSigner(hre.network.config.InstaMaster); @@ -78,7 +78,7 @@ async function getContracts() { hre.network.config.DssCdpManager ); getCdps = await ethers.getContractAt(GetCdps.abi, hre.network.config.GetCdps); - daiToken = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI); + DAI = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI); gelatoCore = await ethers.getContractAt( GelatoCoreLib.GelatoCore.abi, hre.network.config.GelatoCore @@ -122,29 +122,34 @@ async function getContracts() { ); await connectGelatoProviderPayment.deployed(); + const MakerResolver = await ethers.getContractFactory("MakerResolver"); + const makerResolver = await MakerResolver.deploy(); + await makerResolver.deployed(); + return { - connectGelato: connectGelato, - connectMaker: connectMaker, - connectInstaPool: connectInstaPool, - connectCompound: connectCompound, - instaIndex: instaIndex, - instaList: instaList, - instaMapping: instaMapping, - dssCdpManager: dssCdpManager, - getCdps: getCdps, - daiToken: daiToken, - gelatoCore: gelatoCore, - cDaiToken: cDaiToken, - cEthToken: cEthToken, - instaMaster: instaMaster, - instaConnectors: instaConnectors, - compoundResolver: compoundResolver, - conditionMakerVaultUnsafe: conditionMakerVaultUnsafe, - connectGelatoProviderPayment: connectGelatoProviderPayment, - priceOracleResolver: priceOracleResolver, + connectGelato, + connectMaker, + connectInstaPool, + connectCompound, + instaIndex, + instaList, + instaMapping, + dssCdpManager, + getCdps, + DAI, + gelatoCore, + cDaiToken, + cEthToken, + instaMaster, + instaConnectors, + compoundResolver, + conditionMakerVaultUnsafe, + connectGelatoProviderPayment, + priceOracleResolver, dsa: ethers.constants.AddressZero, - connectGelatoDebtBridge: connectGelatoDebtBridge, - debtBridgeFromMaker: debtBridgeFromMaker, + connectGelatoData, + debtBridgeFromMakerForFullRefinance, + makerResolver, }; } diff --git a/test/helpers/setups/Contracts-For-Full-Refinancing-Maker-To-Compound.helper.js b/test/helpers/setups/Contracts-For-Full-Refinancing-Maker-To-Compound.helper.js index 98939d6..81d0ce7 100644 --- a/test/helpers/setups/Contracts-For-Full-Refinancing-Maker-To-Compound.helper.js +++ b/test/helpers/setups/Contracts-For-Full-Refinancing-Maker-To-Compound.helper.js @@ -4,29 +4,29 @@ const {ethers} = hre; const getContracts = require("./Common-Contracts.helper"); async function getAllContracts() { - let connectGelatoDebtBridge; - let debtBridgeFromMaker; + let connectGelatoData; + let debtBridgeFromMakerForFullRefinance; let dsaProviderModule; let contracts = await getContracts(); - const ConnectGelatoDebtBridge = await ethers.getContractFactory( - "ConnectGelatoDebtBridge" + const ConnectGelatoData = await ethers.getContractFactory( + "ConnectGelatoData" ); - connectGelatoDebtBridge = await ConnectGelatoDebtBridge.deploy( + connectGelatoData = await ConnectGelatoData.deploy( (await contracts.instaConnectors.connectorLength()).add(1) ); - await connectGelatoDebtBridge.deployed(); + await connectGelatoData.deployed(); - const DebtBridgeFromMaker = await ethers.getContractFactory( + const DebtBridgeFromMakerForFullRefinance = await ethers.getContractFactory( "DebtBridgeFromMakerForFullRefinance" ); - debtBridgeFromMaker = await DebtBridgeFromMaker.deploy( + debtBridgeFromMakerForFullRefinance = await DebtBridgeFromMakerForFullRefinance.deploy( contracts.connectGelatoProviderPayment.address ); - await debtBridgeFromMaker.deployed(); + await debtBridgeFromMakerForFullRefinance.deployed(); const ProviderModuleDSA = await ethers.getContractFactory( - "ProviderModuleDSAFromMakerToCompound" + "ProviderModuleDsaFromMakerToCompound" ); dsaProviderModule = await ProviderModuleDSA.deploy( hre.network.config.GelatoCore, @@ -34,8 +34,8 @@ async function getAllContracts() { ); await dsaProviderModule.deployed(); - contracts.connectGelatoDebtBridge = connectGelatoDebtBridge; - contracts.debtBridgeFromMaker = debtBridgeFromMaker; + contracts.connectGelatoData = connectGelatoData; + contracts.debtBridgeFromMakerForFullRefinance = debtBridgeFromMakerForFullRefinance; contracts.dsaProviderModule = dsaProviderModule; return contracts; diff --git a/test/helpers/setups/Contracts-For-Full-Refinancing-Maker-To-Maker.helper.js b/test/helpers/setups/Contracts-For-Full-Refinancing-Maker-To-Maker.helper.js index 52e70ca..2f6c1e5 100644 --- a/test/helpers/setups/Contracts-For-Full-Refinancing-Maker-To-Maker.helper.js +++ b/test/helpers/setups/Contracts-For-Full-Refinancing-Maker-To-Maker.helper.js @@ -4,29 +4,29 @@ const {ethers} = hre; const getContracts = require("./Common-Contracts.helper"); async function getAllContracts() { - let connectGelatoDebtBridge; - let debtBridgeFromMaker; + let connectGelatoData; + let debtBridgeFromMakerForFullRefinance; let dsaProviderModule; let contracts = await getContracts(); - const ConnectGelatoDebtBridge = await ethers.getContractFactory( - "ConnectGelatoDebtBridge" + const ConnectGelatoData = await ethers.getContractFactory( + "ConnectGelatoData" ); - connectGelatoDebtBridge = await ConnectGelatoDebtBridge.deploy( + connectGelatoData = await ConnectGelatoData.deploy( (await contracts.instaConnectors.connectorLength()).add(1) ); - await connectGelatoDebtBridge.deployed(); + await connectGelatoData.deployed(); - const DebtBridgeFromMaker = await ethers.getContractFactory( + const DebtBridgeFromMakerForFullRefinance = await ethers.getContractFactory( "DebtBridgeFromMakerForFullRefinance" ); - debtBridgeFromMaker = await DebtBridgeFromMaker.deploy( + debtBridgeFromMakerForFullRefinance = await DebtBridgeFromMakerForFullRefinance.deploy( contracts.connectGelatoProviderPayment.address ); - await debtBridgeFromMaker.deployed(); + await debtBridgeFromMakerForFullRefinance.deployed(); const ProviderModuleDSA = await ethers.getContractFactory( - "ProviderModuleDSAFromMakerToMaker" + "ProviderModuleDsaFromMakerToMaker" ); dsaProviderModule = await ProviderModuleDSA.deploy( hre.network.config.GelatoCore, @@ -34,8 +34,8 @@ async function getAllContracts() { ); await dsaProviderModule.deployed(); - contracts.connectGelatoDebtBridge = connectGelatoDebtBridge; - contracts.debtBridgeFromMaker = debtBridgeFromMaker; + contracts.connectGelatoData = connectGelatoData; + contracts.debtBridgeFromMakerForFullRefinance = debtBridgeFromMakerForFullRefinance; contracts.dsaProviderModule = dsaProviderModule; return contracts; diff --git a/test/helpers/setups/Enabling-New-Connectors-For-Full-Refinance.helper.js b/test/helpers/setups/Enabling-New-Connectors-For-Full-Refinance.helper.js index 23df09a..b7a9c80 100644 --- a/test/helpers/setups/Enabling-New-Connectors-For-Full-Refinance.helper.js +++ b/test/helpers/setups/Enabling-New-Connectors-For-Full-Refinance.helper.js @@ -5,7 +5,7 @@ const {ethers} = hre; async function enableGelatoConnectorsForFromMaker( userWallet, connectGelatoProviderPaymentAddr, - connectGelatoDebtBridgeAddr, + connectGelatoDataAddr, instaMaster, instaConnectors ) { @@ -30,9 +30,7 @@ async function enableGelatoConnectorsForFromMaker( params: [await instaMaster.getAddress()], }); - await instaConnectors - .connect(instaMaster) - .enable(connectGelatoDebtBridgeAddr); + await instaConnectors.connect(instaMaster).enable(connectGelatoDataAddr); await instaConnectors .connect(instaMaster) @@ -43,8 +41,7 @@ async function enableGelatoConnectorsForFromMaker( params: [await instaMaster.getAddress()], }); - expect(await instaConnectors.isConnector([connectGelatoDebtBridgeAddr])).to.be - .true; + expect(await instaConnectors.isConnector([connectGelatoDataAddr])).to.be.true; expect(await instaConnectors.isConnector([connectGelatoProviderPaymentAddr])) .to.be.true; diff --git a/test/helpers/setups/Open-Deposit-Borrow-On-Maker-As-User.helper.js b/test/helpers/setups/Open-Deposit-Borrow-On-Maker-As-User.helper.js index 440ce95..bdf9f8b 100644 --- a/test/helpers/setups/Open-Deposit-Borrow-On-Maker-As-User.helper.js +++ b/test/helpers/setups/Open-Deposit-Borrow-On-Maker-As-User.helper.js @@ -5,7 +5,7 @@ const ConnectMaker = require("../../../pre-compiles/ConnectMaker.json"); async function userOpenDepositBorrowOnMakerVault( userAddress, - daiToken, + DAI, dsa, getCdps, dssCdpManager, @@ -56,7 +56,7 @@ async function userOpenDepositBorrowOnMakerVault( userAddress ); - expect(await daiToken.balanceOf(dsa.address)).to.be.equal(makerInitialDebt); + expect(await DAI.balanceOf(dsa.address)).to.be.equal(makerInitialDebt); //#endregion diff --git a/test/unit_tests/4_ConditionMakerVaultUnsafe.test.js b/test/unit_tests/4_ConditionMakerVaultUnsafe.test.js index a94d369..0a83c6d 100644 --- a/test/unit_tests/4_ConditionMakerVaultUnsafe.test.js +++ b/test/unit_tests/4_ConditionMakerVaultUnsafe.test.js @@ -32,7 +32,7 @@ describe("ConditionMakerVaultUnsafe Unit Test", function () { let dssCdpManager; let instaList; let instaIndex; - let daiToken; + let DAI; let conditionMakerVaultUnsafe; let priceOracleResolver; @@ -66,7 +66,7 @@ describe("ConditionMakerVaultUnsafe Unit Test", function () { DssCdpManager.abi, hre.network.config.DssCdpManager ); - daiToken = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI); + DAI = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI); // ========== Test Setup ============ @@ -141,7 +141,7 @@ describe("ConditionMakerVaultUnsafe Unit Test", function () { userAddress ); - expect(await daiToken.balanceOf(dsa.address)).to.be.equal( + expect(await DAI.balanceOf(dsa.address)).to.be.equal( ethers.utils.parseEther("1000") ); // Add ETH/USD Maker Medianizer in the PriceOracleResolver diff --git a/test/unit_tests/5_ConnectGelatoProviderPayment.test.js b/test/unit_tests/5_ConnectGelatoProviderPayment.test.js index f17803e..e668af2 100644 --- a/test/unit_tests/5_ConnectGelatoProviderPayment.test.js +++ b/test/unit_tests/5_ConnectGelatoProviderPayment.test.js @@ -30,7 +30,7 @@ describe("ConnectGelatoProviderPayment Unit Test", function () { let instaList; let instaIndex; - let daiToken; + let DAI; let instaConnectors; let instaMaster; let connectBasic; @@ -83,7 +83,7 @@ describe("ConnectGelatoProviderPayment Unit Test", function () { DssCdpManager.abi, hre.network.config.DssCdpManager ); - daiToken = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI); + DAI = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI); // ========== Test Setup ============ @@ -140,7 +140,7 @@ describe("ConnectGelatoProviderPayment Unit Test", function () { }); it("#1: payProvider should pay to Provider 300 Dai", async function () { - const providerDAIBalanceBefore = await daiToken.balanceOf(providerAddress); + const providerDAIBalanceBefore = await DAI.balanceOf(providerAddress); await dsa.cast( [hre.network.config.ConnectMaker], @@ -185,7 +185,7 @@ describe("ConnectGelatoProviderPayment Unit Test", function () { userAddress ); - expect(await daiToken.balanceOf(dsa.address)).to.be.equal( + expect(await DAI.balanceOf(dsa.address)).to.be.equal( ethers.utils.parseEther("1000") ); @@ -199,7 +199,7 @@ describe("ConnectGelatoProviderPayment Unit Test", function () { functionname: "payProvider", inputs: [ providerAddress, - daiToken.address, + DAI.address, ethers.utils.parseUnits("300", 18), 0, 0, @@ -209,7 +209,7 @@ describe("ConnectGelatoProviderPayment Unit Test", function () { userAddress ); - expect(await daiToken.balanceOf(providerAddress)).to.be.equal( + expect(await DAI.balanceOf(providerAddress)).to.be.equal( providerDAIBalanceBefore.add(ethers.utils.parseUnits("300", 18)) ); }); @@ -289,6 +289,6 @@ describe("ConnectGelatoProviderPayment Unit Test", function () { value: ethers.utils.parseEther("1"), } ) - ).to.be.revertedWith("ConnectGelatoProviderPayment.payProvider:addr0"); + ).to.be.revertedWith("ConnectGelatoProviderPayment.payProvider:!_provider"); }); }); diff --git a/test/unit_tests/6_DebtRefinanceMath.test.js b/test/unit_tests/6_DebtRefinanceMath.test.js index 51dd942..cbc642f 100644 --- a/test/unit_tests/6_DebtRefinanceMath.test.js +++ b/test/unit_tests/6_DebtRefinanceMath.test.js @@ -23,13 +23,15 @@ describe("Debt Partial Refinance Math Unit Test", function () { process.exit(1); } - let debtRefinanceMath; + let debtBridgeFromMakerForPartialRefinance; before(async function () { - const DebtRefinanceMath = await ethers.getContractFactory( - "DebtRefinanceMath" + const DebtBridgeFromMakerForPartialRefinance = await ethers.getContractFactory( + "DebtBridgeFromMakerForPartialRefinance" ); - debtRefinanceMath = await DebtRefinanceMath.deploy(); - debtRefinanceMath.deployed(); + debtBridgeFromMakerForPartialRefinance = await DebtBridgeFromMakerForPartialRefinance.deploy( + ethers.constants.AddressZero + ); + debtBridgeFromMakerForPartialRefinance.deployed(); }); it("#1: wCalcCollateralToWithdraw should return the amount of collateral to withdraw on protocol 1 and to put on protocol 2", async function () { @@ -71,7 +73,7 @@ describe("Debt Partial Refinance Math Unit Test", function () { //#endregion expect( - await debtRefinanceMath.wCalcCollateralToWithdraw( + await debtBridgeFromMakerForPartialRefinance.wCalcCollateralToWithdraw( minColRatioOnMaker, minColRatioOnPositionB, collateralPrice, @@ -121,7 +123,7 @@ describe("Debt Partial Refinance Math Unit Test", function () { //#endregion expect( - await debtRefinanceMath.wCalcDebtToRepay( + await debtBridgeFromMakerForPartialRefinance.wCalcDebtToRepay( minColRatioOnMaker, minColRatioOnPositionB, collateral, diff --git a/test_temp/3_Partial-Refinance-External-Provider.test.js b/test_temp/3_Partial-Refinance-External-Provider.test.js index 806cca5..354b3e8 100644 --- a/test_temp/3_Partial-Refinance-External-Provider.test.js +++ b/test_temp/3_Partial-Refinance-External-Provider.test.js @@ -13,9 +13,9 @@ const ConnectMaker = require("../pre-compiles/ConnectMaker.json"); const ConnectCompound = require("../pre-compiles/ConnectCompound.json"); const ConnectInstaPool = require("../pre-compiles/ConnectInstaPool.json"); const ConnectAuth = require("../pre-compiles/ConnectAuth.json"); -const ConnectGelatoFullDebtBridgeFromMakerABI = require("../artifacts/contracts/connectors/ConnectGelatoPartialDebtBridgeFromMaker.sol/ConnectGelatoPartialDebtBridgeFromMaker.json") +const ConnectGelatoFullDebtBridgeFromMakerABI = require("../artifacts/contracts/contracts/connectors/ConnectGelatoPartialDebtBridgeFromMaker.sol/ConnectGelatoPartialDebtBridgeFromMaker.json") .abi; -const ConnectGelatoProviderPaymentABI = require("../artifacts/contracts/connectors/ConnectGelatoProviderPayment.sol/ConnectGelatoProviderPayment.json") +const ConnectGelatoProviderPaymentABI = require("../artifacts/contracts/contracts/connectors/ConnectGelatoProviderPayment.sol/ConnectGelatoProviderPayment.json") .abi; const InstaConnector = require("../pre-compiles/InstaConnectors.json"); const DssCdpManager = require("../pre-compiles/DssCdpManager.json"); @@ -23,7 +23,7 @@ const GetCdps = require("../pre-compiles/GetCdps.json"); const IERC20 = require("../pre-compiles/IERC20.json"); const CTokenInterface = require("../pre-compiles/CTokenInterface.json"); const CompoundResolver = require("../pre-compiles/InstaCompoundResolver.json"); -const PriceOracleResolverABI = require("../artifacts/contracts/resolvers/PriceOracleResolver.sol/PriceOracleResolver.json") +const PriceOracleResolverABI = require("../artifacts/contracts/contracts/resolvers/PriceOracleResolver.sol/PriceOracleResolver.json") .abi; const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; @@ -138,7 +138,7 @@ describe("Debt Bridge with External Provider", function () { let instaList; let dssCdpManager; let getCdps; - let daiToken; + let DAI; let gelatoCore; let cDaiToken; let cEthToken; @@ -211,7 +211,7 @@ describe("Debt Bridge with External Provider", function () { GetCdps.abi, hre.network.config.GetCdps ); - daiToken = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI); + DAI = await ethers.getContractAt(IERC20.abi, hre.network.config.DAI); gelatoCore = await ethers.getContractAt( GelatoCoreLib.GelatoCore.abi, hre.network.config.GelatoCore @@ -501,9 +501,7 @@ describe("Debt Bridge with External Provider", function () { userAddress ); - expect(await daiToken.balanceOf(dsa.address)).to.be.equal( - MAKER_INITIAL_DEBT - ); + expect(await DAI.balanceOf(dsa.address)).to.be.equal(MAKER_INITIAL_DEBT); //#endregion @@ -925,9 +923,7 @@ describe("Debt Bridge with External Provider", function () { ).to.be.lt(ethers.utils.parseUnits("1", 1)); // DSA contain 1000 DAI - expect(await daiToken.balanceOf(dsa.address)).to.be.equal( - MAKER_INITIAL_DEBT - ); + expect(await DAI.balanceOf(dsa.address)).to.be.equal(MAKER_INITIAL_DEBT); //#endregion }); diff --git a/yarn.lock b/yarn.lock index aac16f6..6f3e875 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,18 +55,18 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@ethereum-waffle/chai@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.1.2.tgz#f1a15085f6ab67397d1bfe89ec97938309f2d941" - integrity sha512-+rlfrBlWleY2zCjkR3tH9pleKHx10atI4CQ03ZKz4bw0sCU8FtD3Bq7pEt6gMWMpVH7h5hlemBTT++1hED9jyA== +"@ethereum-waffle/chai@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.2.0.tgz#f75465e447358db0fde967b26cf10adbe5365380" + integrity sha512-3mvI7luX8FSAX2yjklSN8rw8F8RNaMzZDadDkS9JvmoM4khByGe3mDn8rVroneBAcFusXJfL6BEssGj5S4mD7Q== dependencies: - "@ethereum-waffle/provider" "^3.1.2" + "@ethereum-waffle/provider" "^3.2.0" ethers "^5.0.0" -"@ethereum-waffle/compiler@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.1.2.tgz#4df177bc1c6b369061062514f166183181954abd" - integrity sha512-ko8fc1CYilS6txrNeyNgArRYgw1+cBKzs0nY6ZYPbxN6ywdm0efpcdYHuKPh8L0KeH5w9dIoKNkCLjL+vUEFjA== +"@ethereum-waffle/compiler@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.2.0.tgz#3d5cccc8171ff61a0069d9558fb567ddd45b6b4e" + integrity sha512-Tg8YjbcVKQkNwhbiBf9Z4kKPolPO0IB+iYwAdpXNwgyMOH74guIHhFGtKOCPoY4VXR75erGgeQIt2PzIn/szCA== dependencies: "@resolver-engine/imports" "^0.3.3" "@resolver-engine/imports-fs" "^0.3.3" @@ -77,29 +77,29 @@ node-fetch "^2.6.0" solc "^0.6.3" -"@ethereum-waffle/ens@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-3.1.2.tgz#ed21ea9c376ec21f3c02649cc158cb60a69d94e9" - integrity sha512-otoTGCClgCbyNQ7YStyTtFkCYo+K9XKslijOcTOGBHEp/tbij76fToXMp6EPUGaNg2mbNrWw9H8x6Glp7UD8iw== +"@ethereum-waffle/ens@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-3.2.0.tgz#26f7b2048a422eae5ce39a855e519e01ebc06953" + integrity sha512-n4EYJDLAwN2X+2EsZMasXRlz5gYp39Tmy18RU4f6ZdnTNuVNw1BNkCC9VzrQooHGvHLjKZFPvcl+FRfBO+Xcyw== dependencies: "@ensdomains/ens" "^0.4.4" "@ensdomains/resolver" "^0.2.4" ethers "^5.0.1" -"@ethereum-waffle/mock-contract@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.1.2.tgz#4dd3c02454b797ad7a8e5d42fbd20eaee75af3cc" - integrity sha512-P3AZGqVWE1ZJ3Gqiko/oPC4CfnNSbHwq2awNsa4HLj2URHeRE5fIQMuAxCT3bCwf4QGdE7yxOVkFHDLu40hNuw== +"@ethereum-waffle/mock-contract@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.2.0.tgz#be9441060f8b58f1d7e344f74e5dd158d41a7c45" + integrity sha512-TfBt9ka2DXVxxIBee3WB0gSLgWCo9ZegqcdXjCz0QGlu+dEhL8W3+aLDYQoyx3kwlecfNl8EQ1V7g7GH8wrlMg== dependencies: "@ethersproject/abi" "^5.0.1" ethers "^5.0.1" -"@ethereum-waffle/provider@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-3.1.2.tgz#8ff1d98b3725c9abbdd1b13d47784eccf57ae1e5" - integrity sha512-RQTt87qmPJOFqF3QP1ASSt/kGUB2WJKfEwFMuAMP9ZQ2icRXtyLXseU4dKNAU0gc/BckqrXk5r1xzirwJp+ANg== +"@ethereum-waffle/provider@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-3.2.0.tgz#501d4bbf04ffc01dced0107dcc9e20f24354387f" + integrity sha512-U9KyjMKIZuK4gi2kzWIJkAXYjtg0aIlEQ0F4yKqHMRyqAiSM6M4VJgn6tHisxe3Ev9z/jSnutKT8dyAEwlIYdw== dependencies: - "@ethereum-waffle/ens" "^3.1.2" + "@ethereum-waffle/ens" "^3.2.0" ethers "^5.0.1" ganache-core "^2.10.2" patch-package "^6.2.2" @@ -2239,10 +2239,10 @@ commander@3.0.2: resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== -commander@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc" - integrity sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA== +commander@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.0.tgz#b990bfb8ac030aedc6d11bc04d1488ffef56db75" + integrity sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q== compare-versions@^3.6.0: version "3.6.0" @@ -2471,7 +2471,7 @@ debug@3.2.6, debug@^3.1.0: dependencies: ms "^2.1.1" -debug@4, debug@^4.0.1, debug@^4.1.1: +debug@4, debug@^4.0.1, debug@^4.1.1, debug@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== @@ -2843,10 +2843,10 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-config-prettier@6.14.0: - version "6.14.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.14.0.tgz#390e7863a8ae99970981933826476169285b3a27" - integrity sha512-DbVwh0qZhAC7CNDWcq8cBdK6FcVHiMTKmCypOPWeZkp9hJ8xYwTaWSa6bb6cjfi8KOeJy0e9a8Izxyx+O4+gCQ== +eslint-config-prettier@6.15.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" + integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw== dependencies: get-stdin "^6.0.0" @@ -3214,15 +3214,15 @@ ethereum-cryptography@^0.1.2, ethereum-cryptography@^0.1.3: secp256k1 "^4.0.1" setimmediate "^1.0.5" -ethereum-waffle@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.1.2.tgz#54ab4049d256185bb50de4e86328e521ea2ad816" - integrity sha512-q9fI4N2RN+OEIXoWpyj8LWhjaBNtIxKID9RHHIvWe32Jp5nRN8F3Ja+EAaJ5Qh3/eZMPdpauW4N5zBrY2qXQpQ== +ethereum-waffle@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.2.0.tgz#1cea66fece731ea281e9d68046056caed2f2af84" + integrity sha512-XmLvbGE47u+6haOT/vBwx/2ifemlKv4Uop1ebnccnBXD0xmTK2Qnk/FonwHtkHX+cUxj+Ax+3c/1fYDogEvcZw== dependencies: - "@ethereum-waffle/chai" "^3.1.2" - "@ethereum-waffle/compiler" "^3.1.2" - "@ethereum-waffle/mock-contract" "^3.1.2" - "@ethereum-waffle/provider" "^3.1.2" + "@ethereum-waffle/chai" "^3.2.0" + "@ethereum-waffle/compiler" "^3.2.0" + "@ethereum-waffle/mock-contract" "^3.2.0" + "@ethereum-waffle/provider" "^3.2.0" ethers "^5.0.1" ethereumjs-abi@0.6.5: @@ -3543,10 +3543,10 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -execa@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.0.3.tgz#0a34dabbad6d66100bd6f2c576c8669403f317f2" - integrity sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A== +execa@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== dependencies: cross-spawn "^7.0.0" get-stream "^5.0.0" @@ -5211,20 +5211,20 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -lint-staged@10.5.0: - version "10.5.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.0.tgz#c923c2447a84c595874f3de696778736227e7a7a" - integrity sha512-gjC9+HGkBubOF+Yyoj9pd52Qfm/kYB+dRX1UOgWjHKvSDYl+VHkZXlBMlqSZa2cH3Kp5/uNL480sV6e2dTgXSg== +lint-staged@10.5.1: + version "10.5.1" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.1.tgz#901e915c2360072dded0e7d752a0d9a49e079daa" + integrity sha512-fTkTGFtwFIJJzn/PbUO3RXyEBHIhbfYBE7+rJyLcOXabViaO/h6OslgeK6zpeUtzkDrzkgyAYDTLAwx6JzDTHw== dependencies: chalk "^4.1.0" cli-truncate "^2.1.0" - commander "^6.0.0" + commander "^6.2.0" cosmiconfig "^7.0.0" - debug "^4.1.1" + debug "^4.2.0" dedent "^0.7.0" enquirer "^2.3.6" - execa "^4.0.3" - listr2 "^2.6.0" + execa "^4.1.0" + listr2 "^3.2.2" log-symbols "^4.0.0" micromatch "^4.0.2" normalize-path "^3.0.0" @@ -5232,10 +5232,10 @@ lint-staged@10.5.0: string-argv "0.3.1" stringify-object "^3.3.0" -listr2@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.2.tgz#4912eb01e1e2dd72ec37f3895a56bf2622d6f36a" - integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA== +listr2@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.2.2.tgz#d20feb75015e506992b55af40722ba1af168b8f1" + integrity sha512-AajqcZEUikF2ioph6PfH3dIuxJclhr3i3kHgTOP0xeXdWQohrvJAAmqVcV43/GI987HFY/vzT73jYXoa4esDHg== dependencies: chalk "^4.1.0" cli-truncate "^2.1.0" @@ -5243,7 +5243,7 @@ listr2@^2.6.0: indent-string "^4.0.0" log-update "^4.0.0" p-map "^4.0.0" - rxjs "^6.6.2" + rxjs "^6.6.3" through "^2.3.8" load-json-file@^1.0.0: @@ -6848,7 +6848,7 @@ rustbn.js@~0.2.0: resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== -rxjs@^6.4.0, rxjs@^6.6.2: +rxjs@^6.4.0, rxjs@^6.6.3: version "6.6.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== @@ -7185,10 +7185,10 @@ solhint-plugin-prettier@0.0.5: dependencies: prettier-linter-helpers "^1.0.0" -solhint@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.0.tgz#4c7786480d25986ad25f0199fff334c07189a9a4" - integrity sha512-vnTGzsX2UzxbsIgH5ib2CXorbGywi1vjOOMPXrlyufhg3oRS7IL6cj7oriYMk6fZiml3GvvA/xo1HdaWKhWJEQ== +solhint@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.1.tgz#7aa02afb79ad2bcfa64885b1fe134e220949546f" + integrity sha512-JXAOLM2UQrLOtx4fKXzleq6CR0N7AlRfki+dFyvab93x4DoHeHQ4Ic2LMScT8V0AddXgbKtR8xdIIZKLh07dNg== dependencies: "@solidity-parser/parser" "^0.8.1" ajv "^6.6.1"