From fc2c5974979b02b9d53db3c596f38139afe7929c Mon Sep 17 00:00:00 2001 From: Shivva Date: Wed, 18 Aug 2021 21:30:56 +0200 Subject: [PATCH 1/7] Aave protection connector --- .../aave-services/protection/helpers.sol | 18 ++ .../aave-services/protection/interface.sol | 80 +++++++++ .../gelato/aave-services/protection/main.sol | 155 ++++++++++++++++++ 3 files changed, 253 insertions(+) create mode 100644 contracts/polygon/connectors/gelato/aave-services/protection/helpers.sol create mode 100644 contracts/polygon/connectors/gelato/aave-services/protection/interface.sol create mode 100644 contracts/polygon/connectors/gelato/aave-services/protection/main.sol diff --git a/contracts/polygon/connectors/gelato/aave-services/protection/helpers.sol b/contracts/polygon/connectors/gelato/aave-services/protection/helpers.sol new file mode 100644 index 00000000..1f43b799 --- /dev/null +++ b/contracts/polygon/connectors/gelato/aave-services/protection/helpers.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.6; + +import {LendingPoolInterface, AaveServicesInterface} from "./interface.sol"; + +abstract contract Helpers { + // solhint-disable-next-line const-name-snakecase + LendingPoolInterface internal constant _lendingPool = + LendingPoolInterface(0x8dFf5E27EA6b7AC08EbFdf9eB090F32ee9a30fcf); + + // solhint-disable-next-line const-name-snakecase + AaveServicesInterface internal constant _aaveServices = + AaveServicesInterface(0x18FAbC997fDd624764E1974b283B1b904b66d613); + + // solhint-disable-next-line const-name-snakecase + address internal constant _protectionAction = + 0xc38b6dbd0F84777AA4fae2d36FE1506428A22b9B; +} diff --git a/contracts/polygon/connectors/gelato/aave-services/protection/interface.sol b/contracts/polygon/connectors/gelato/aave-services/protection/interface.sol new file mode 100644 index 00000000..097afb22 --- /dev/null +++ b/contracts/polygon/connectors/gelato/aave-services/protection/interface.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.6; +pragma abicoder v2; + +struct ReserveData { + //stores the reserve configuration + ReserveConfigurationMap configuration; + //the liquidity index. Expressed in ray + uint128 liquidityIndex; + //variable borrow index. Expressed in ray + uint128 variableBorrowIndex; + //the current supply rate. Expressed in ray + uint128 currentLiquidityRate; + //the current variable borrow rate. Expressed in ray + uint128 currentVariableBorrowRate; + //the current stable borrow rate. Expressed in ray + uint128 currentStableBorrowRate; + uint40 lastUpdateTimestamp; + //tokens addresses + address aTokenAddress; + address stableDebtTokenAddress; + address variableDebtTokenAddress; + //address of the interest rate strategy + address interestRateStrategyAddress; + //the id of the reserve. Represents the position in the list of the active reserves + uint8 id; +} + +struct ReserveConfigurationMap { + //bit 0-15: LTV + //bit 16-31: Liq. threshold + //bit 32-47: Liq. bonus + //bit 48-55: Decimals + //bit 56: Reserve is active + //bit 57: reserve is frozen + //bit 58: borrowing is enabled + //bit 59: stable rate borrowing enabled + //bit 60-63: reserved + //bit 64-79: reserve factor + uint256 data; +} + +interface LendingPoolInterface { + function getReservesList() external view returns (address[] memory); + + function getReserveData(address asset) + external + view + returns (ReserveData memory); +} + +interface AaveServicesInterface { + function submitTask( + address _action, + bytes memory _taskData, + bool _isPermanent + ) external; + + function cancelTask(address _action) external; + + function updateTask( + address _action, + bytes memory _data, + bool _isPermanent + ) external; + + function taskByUsersAction(address _user, address _action) + external + view + returns (bytes32); +} + +interface IERC20 { + function approve(address spender, uint256 amount) external returns (bool); + + function allowance(address owner, address spender) + external + view + returns (uint256); +} diff --git a/contracts/polygon/connectors/gelato/aave-services/protection/main.sol b/contracts/polygon/connectors/gelato/aave-services/protection/main.sol new file mode 100644 index 00000000..7ed7bc9a --- /dev/null +++ b/contracts/polygon/connectors/gelato/aave-services/protection/main.sol @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.6; +pragma abicoder v2; + +/** + * @title Aave Protection. + * @dev Protect DSA against Liquidation risk on Aave with Gelato. + */ + + +import {IERC20} from "./interface.sol"; +import {Helpers} from "./helpers.sol"; + +abstract contract GAaveProtectionResolver is Helpers { + /// @dev Function for submitting a protection task + /// @param _wantedHealthFactor targeted health after protection. + /// @param _minimumHealthFactor trigger protection when current health + /// factor is below _minimumHealthFactor. + /// @param _isPermanent boolean to set a protection as permanent + function submitProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) external payable { + _submitProtection( + _wantedHealthFactor, + _minimumHealthFactor, + _isPermanent + ); + } + + /// @dev Function for modifying a protection task + /// @param _wantedHealthFactor targeted health after protection. + /// @param _minimumHealthFactor trigger protection when current health + /// factor is below _minimumHealthFactor. + /// @param _isPermanent boolean to set a protection as permanent + function updateProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) external payable { + _updateProtection( + _wantedHealthFactor, + _minimumHealthFactor, + _isPermanent + ); + } + + /// @dev Function for cancelling a protection task + function cancelProtection() external payable { + _cancelProtection(); + } + + /// @dev Function for cancelling and removing allowance + /// of aToken to _protectionAction + function cancelAndRevoke() external payable { + if (_dsaHasProtection()) _cancelProtection(); + _revokeAllowance(); + } + + function _submitProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) internal { + _giveAllowance(); + + _aaveServices.submitTask( + _protectionAction, + abi.encode( + _wantedHealthFactor, + _minimumHealthFactor, + address(this) + ), + _isPermanent + ); + } + + function _updateProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) internal { + _giveAllowance(); + + _aaveServices.updateTask( + _protectionAction, + abi.encode( + _wantedHealthFactor, + _minimumHealthFactor, + address(this) + ), + _isPermanent + ); + } + + function _cancelProtection() internal { + _aaveServices.cancelTask(_protectionAction); + } + + function _giveAllowance() internal { + address[] memory aTokenList = _getATokenList(); + for (uint256 i = 0; i < aTokenList.length; i++) { + if ( + !(IERC20(aTokenList[i]).allowance( + address(this), + _protectionAction + ) == type(uint256).max) + ) { + IERC20(aTokenList[i]).approve( + _protectionAction, + type(uint256).max + ); + } + } + } + + function _revokeAllowance() internal { + address[] memory aTokenList = _getATokenList(); + for (uint256 i = 0; i < aTokenList.length; i++) { + if ( + !(IERC20(aTokenList[i]).allowance( + address(this), + _protectionAction + ) == 0) + ) { + IERC20(aTokenList[i]).approve(_protectionAction, 0); + } + } + } + + function _getATokenList() + internal + view + returns (address[] memory aTokenList) + { + address[] memory underlyingsList = _lendingPool.getReservesList(); + aTokenList = new address[](underlyingsList.length); + for (uint256 i = 0; i < underlyingsList.length; i++) { + aTokenList[i] = (_lendingPool.getReserveData(underlyingsList[i])) + .aTokenAddress; + } + } + + function _dsaHasProtection() internal view returns (bool) { + return + _aaveServices.taskByUsersAction(address(this), _protectionAction) != + bytes32(0); + } +} + +contract GAaveProtectionPolygonConnector is GAaveProtectionResolver { + // solhint-disable-next-line const-name-snakecase + string public constant name = "GelatoAaveProtectionPolygonConnector-v1"; +} From cd46f4fae83e7ac110a28c9b66f022883613865f Mon Sep 17 00:00:00 2001 From: Shivva Date: Sat, 21 Aug 2021 11:34:40 +0200 Subject: [PATCH 2/7] chore: internals inside helpers, add events. --- .../aave-services/protection/events.sol | 20 +++ .../aave-services/protection/helpers.sol | 97 ++++++++++++++- .../gelato/aave-services/protection/main.sol | 116 ++++-------------- 3 files changed, 137 insertions(+), 96 deletions(-) create mode 100644 contracts/polygon/connectors/gelato/aave-services/protection/events.sol diff --git a/contracts/polygon/connectors/gelato/aave-services/protection/events.sol b/contracts/polygon/connectors/gelato/aave-services/protection/events.sol new file mode 100644 index 00000000..dc9d7711 --- /dev/null +++ b/contracts/polygon/connectors/gelato/aave-services/protection/events.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.6; + +contract Events { + event LogSubmitProtection( + address indexed dsa, + address indexed action, + uint256 wantedHealthFactor, + uint256 minimumHealthFactor, + bool isPermanent + ); + event LogUpdateProtection( + address indexed dsa, + address indexed action, + uint256 wantedHealthFactor, + uint256 minimumHealthFactor, + bool isPermanent + ); + event LogCancelProtection(address indexed dsa, address indexed action); +} diff --git a/contracts/polygon/connectors/gelato/aave-services/protection/helpers.sol b/contracts/polygon/connectors/gelato/aave-services/protection/helpers.sol index 1f43b799..eb41d5cb 100644 --- a/contracts/polygon/connectors/gelato/aave-services/protection/helpers.sol +++ b/contracts/polygon/connectors/gelato/aave-services/protection/helpers.sol @@ -1,7 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.7.6; +pragma abicoder v2; -import {LendingPoolInterface, AaveServicesInterface} from "./interface.sol"; +import { + LendingPoolInterface, + AaveServicesInterface, + IERC20 +} from "./interface.sol"; abstract contract Helpers { // solhint-disable-next-line const-name-snakecase @@ -15,4 +20,94 @@ abstract contract Helpers { // solhint-disable-next-line const-name-snakecase address internal constant _protectionAction = 0xc38b6dbd0F84777AA4fae2d36FE1506428A22b9B; + + function _cancelProtection() internal { + _aaveServices.cancelTask(_protectionAction); + } + + function _submitProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) internal { + _giveAllowance(); + + _aaveServices.submitTask( + _protectionAction, + abi.encode( + _wantedHealthFactor, + _minimumHealthFactor, + address(this) + ), + _isPermanent + ); + } + + function _updateProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) internal { + _giveAllowance(); + + _aaveServices.updateTask( + _protectionAction, + abi.encode( + _wantedHealthFactor, + _minimumHealthFactor, + address(this) + ), + _isPermanent + ); + } + + function _giveAllowance() internal { + address[] memory aTokenList = _getATokenList(); + for (uint256 i = 0; i < aTokenList.length; i++) { + if ( + !(IERC20(aTokenList[i]).allowance( + address(this), + _protectionAction + ) == type(uint256).max) + ) { + IERC20(aTokenList[i]).approve( + _protectionAction, + type(uint256).max + ); + } + } + } + + function _revokeAllowance() internal { + address[] memory aTokenList = _getATokenList(); + for (uint256 i = 0; i < aTokenList.length; i++) { + if ( + !(IERC20(aTokenList[i]).allowance( + address(this), + _protectionAction + ) == 0) + ) { + IERC20(aTokenList[i]).approve(_protectionAction, 0); + } + } + } + + function _getATokenList() + internal + view + returns (address[] memory aTokenList) + { + address[] memory underlyingsList = _lendingPool.getReservesList(); + aTokenList = new address[](underlyingsList.length); + for (uint256 i = 0; i < underlyingsList.length; i++) { + aTokenList[i] = (_lendingPool.getReserveData(underlyingsList[i])) + .aTokenAddress; + } + } + + function _dsaHasProtection() internal view returns (bool) { + return + _aaveServices.taskByUsersAction(address(this), _protectionAction) != + bytes32(0); + } } diff --git a/contracts/polygon/connectors/gelato/aave-services/protection/main.sol b/contracts/polygon/connectors/gelato/aave-services/protection/main.sol index 7ed7bc9a..f6a879c3 100644 --- a/contracts/polygon/connectors/gelato/aave-services/protection/main.sol +++ b/contracts/polygon/connectors/gelato/aave-services/protection/main.sol @@ -1,17 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity 0.7.6; -pragma abicoder v2; /** * @title Aave Protection. * @dev Protect DSA against Liquidation risk on Aave with Gelato. */ - -import {IERC20} from "./interface.sol"; +import {Events} from "./events.sol"; import {Helpers} from "./helpers.sol"; -abstract contract GAaveProtectionResolver is Helpers { +abstract contract GAaveProtectionResolver is Events, Helpers { /// @dev Function for submitting a protection task /// @param _wantedHealthFactor targeted health after protection. /// @param _minimumHealthFactor trigger protection when current health @@ -27,6 +25,13 @@ abstract contract GAaveProtectionResolver is Helpers { _minimumHealthFactor, _isPermanent ); + emit LogSubmitProtection( + address(this), + _protectionAction, + _wantedHealthFactor, + _minimumHealthFactor, + _isPermanent + ); } /// @dev Function for modifying a protection task @@ -44,109 +49,30 @@ abstract contract GAaveProtectionResolver is Helpers { _minimumHealthFactor, _isPermanent ); + emit LogUpdateProtection( + address(this), + _protectionAction, + _wantedHealthFactor, + _minimumHealthFactor, + _isPermanent + ); } /// @dev Function for cancelling a protection task function cancelProtection() external payable { _cancelProtection(); + emit LogCancelProtection(address(this), _protectionAction); } /// @dev Function for cancelling and removing allowance /// of aToken to _protectionAction function cancelAndRevoke() external payable { - if (_dsaHasProtection()) _cancelProtection(); + if (_dsaHasProtection()) { + _cancelProtection(); + emit LogCancelProtection(address(this), _protectionAction); + } _revokeAllowance(); } - - function _submitProtection( - uint256 _wantedHealthFactor, - uint256 _minimumHealthFactor, - bool _isPermanent - ) internal { - _giveAllowance(); - - _aaveServices.submitTask( - _protectionAction, - abi.encode( - _wantedHealthFactor, - _minimumHealthFactor, - address(this) - ), - _isPermanent - ); - } - - function _updateProtection( - uint256 _wantedHealthFactor, - uint256 _minimumHealthFactor, - bool _isPermanent - ) internal { - _giveAllowance(); - - _aaveServices.updateTask( - _protectionAction, - abi.encode( - _wantedHealthFactor, - _minimumHealthFactor, - address(this) - ), - _isPermanent - ); - } - - function _cancelProtection() internal { - _aaveServices.cancelTask(_protectionAction); - } - - function _giveAllowance() internal { - address[] memory aTokenList = _getATokenList(); - for (uint256 i = 0; i < aTokenList.length; i++) { - if ( - !(IERC20(aTokenList[i]).allowance( - address(this), - _protectionAction - ) == type(uint256).max) - ) { - IERC20(aTokenList[i]).approve( - _protectionAction, - type(uint256).max - ); - } - } - } - - function _revokeAllowance() internal { - address[] memory aTokenList = _getATokenList(); - for (uint256 i = 0; i < aTokenList.length; i++) { - if ( - !(IERC20(aTokenList[i]).allowance( - address(this), - _protectionAction - ) == 0) - ) { - IERC20(aTokenList[i]).approve(_protectionAction, 0); - } - } - } - - function _getATokenList() - internal - view - returns (address[] memory aTokenList) - { - address[] memory underlyingsList = _lendingPool.getReservesList(); - aTokenList = new address[](underlyingsList.length); - for (uint256 i = 0; i < underlyingsList.length; i++) { - aTokenList[i] = (_lendingPool.getReserveData(underlyingsList[i])) - .aTokenAddress; - } - } - - function _dsaHasProtection() internal view returns (bool) { - return - _aaveServices.taskByUsersAction(address(this), _protectionAction) != - bytes32(0); - } } contract GAaveProtectionPolygonConnector is GAaveProtectionResolver { From 059412ebcb471b4e56647c32d441a07a45fb0997 Mon Sep 17 00:00:00 2001 From: Shivva Date: Sat, 21 Aug 2021 13:11:21 +0200 Subject: [PATCH 3/7] add LogCancelAndRevoke event --- .../connectors/gelato/aave-services/protection/events.sol | 1 + .../connectors/gelato/aave-services/protection/main.sol | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/contracts/polygon/connectors/gelato/aave-services/protection/events.sol b/contracts/polygon/connectors/gelato/aave-services/protection/events.sol index dc9d7711..813d521c 100644 --- a/contracts/polygon/connectors/gelato/aave-services/protection/events.sol +++ b/contracts/polygon/connectors/gelato/aave-services/protection/events.sol @@ -17,4 +17,5 @@ contract Events { bool isPermanent ); event LogCancelProtection(address indexed dsa, address indexed action); + event LogCancelAndRevoke(address indexed dsa, address indexed action); } diff --git a/contracts/polygon/connectors/gelato/aave-services/protection/main.sol b/contracts/polygon/connectors/gelato/aave-services/protection/main.sol index f6a879c3..b948af67 100644 --- a/contracts/polygon/connectors/gelato/aave-services/protection/main.sol +++ b/contracts/polygon/connectors/gelato/aave-services/protection/main.sol @@ -67,11 +67,9 @@ abstract contract GAaveProtectionResolver is Events, Helpers { /// @dev Function for cancelling and removing allowance /// of aToken to _protectionAction function cancelAndRevoke() external payable { - if (_dsaHasProtection()) { - _cancelProtection(); - emit LogCancelProtection(address(this), _protectionAction); - } + if (_dsaHasProtection()) _cancelProtection(); _revokeAllowance(); + emit LogCancelAndRevoke(address(this), _protectionAction); } } From d7e765e5e85c9fb659b0611e90aa52ff43b36d67 Mon Sep 17 00:00:00 2001 From: Shivva Date: Fri, 10 Sep 2021 12:02:23 +0200 Subject: [PATCH 4/7] aave protection connector deployment --- docs/connectors.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/connectors.json b/docs/connectors.json index 92efaa2c..6979490c 100644 --- a/docs/connectors.json +++ b/docs/connectors.json @@ -32,7 +32,8 @@ "AUTHORITY-A": "0xf73C94402BC24148b744083eD02654EEc2C37D5B", "BASIC-A": "0x1cAF5EC802ca602E98139AD96A8f2B7BC524264E", "AAVE-CLAIM-A": "0xC7Cb1dE2721BFC0E0DA1b9D526bCdC54eF1C0eFC", - "PARASWAP-A": "0xFb3a1D56eD56F046721B9aCa749895100754578b" + "PARASWAP-A": "0xFb3a1D56eD56F046721B9aCa749895100754578b", + "AAVE-PROT-A": "0x177Bd89A1D8643C9525D2DF131C1a6C513869299" } }, "mappings": { From e04778e43a500a777d8f8d881d882a8fb63ac354 Mon Sep 17 00:00:00 2001 From: Shivva Date: Thu, 23 Sep 2021 17:05:33 +0200 Subject: [PATCH 5/7] Adding aave protection connector mainnet --- .../aave-services/protection/events.sol | 21 ++++ .../aave-services/protection/helpers.sol | 113 ++++++++++++++++++ .../aave-services/protection/interface.sol | 80 +++++++++++++ .../gelato/aave-services/protection/main.sol | 80 +++++++++++++ docs/connectors.json | 3 +- 5 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 contracts/mainnet/connectors/gelato/aave-services/protection/events.sol create mode 100644 contracts/mainnet/connectors/gelato/aave-services/protection/helpers.sol create mode 100644 contracts/mainnet/connectors/gelato/aave-services/protection/interface.sol create mode 100644 contracts/mainnet/connectors/gelato/aave-services/protection/main.sol diff --git a/contracts/mainnet/connectors/gelato/aave-services/protection/events.sol b/contracts/mainnet/connectors/gelato/aave-services/protection/events.sol new file mode 100644 index 00000000..3cf7e9f7 --- /dev/null +++ b/contracts/mainnet/connectors/gelato/aave-services/protection/events.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.6; + +contract Events { + event LogSubmitProtection( + address indexed dsa, + address indexed action, + uint256 wantedHealthFactor, + uint256 minimumHealthFactor, + bool isPermanent + ); + event LogUpdateProtection( + address indexed dsa, + address indexed action, + uint256 wantedHealthFactor, + uint256 minimumHealthFactor, + bool isPermanent + ); + event LogCancelProtection(address indexed dsa, address indexed action); + event LogCancelAndRevoke(address indexed dsa, address indexed action); +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/gelato/aave-services/protection/helpers.sol b/contracts/mainnet/connectors/gelato/aave-services/protection/helpers.sol new file mode 100644 index 00000000..b795486a --- /dev/null +++ b/contracts/mainnet/connectors/gelato/aave-services/protection/helpers.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.6; +pragma abicoder v2; + +import { + LendingPoolInterface, + AaveServicesInterface, + IERC20 +} from "./interface.sol"; + +abstract contract Helpers { + // solhint-disable-next-line const-name-snakecase + LendingPoolInterface internal constant _lendingPool = + LendingPoolInterface(0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9); + + // solhint-disable-next-line const-name-snakecase + AaveServicesInterface internal constant _aaveServices = + AaveServicesInterface(0xE3d373c78803C1d22cE96bdC43d47542835bBF42); + + // solhint-disable-next-line const-name-snakecase + address internal constant _protectionAction = + 0xD2579361F3C402938841774ECc1acdd51d3a4345; + + function _submitProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) internal { + _giveAllowance(); + + _aaveServices.submitTask( + _protectionAction, + abi.encode( + _wantedHealthFactor, + _minimumHealthFactor, + address(this) + ), + _isPermanent + ); + } + + function _updateProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) internal { + _giveAllowance(); + + _aaveServices.updateTask( + _protectionAction, + abi.encode( + _wantedHealthFactor, + _minimumHealthFactor, + address(this) + ), + _isPermanent + ); + } + + function _cancelProtection() internal { + _aaveServices.cancelTask(_protectionAction); + } + + function _giveAllowance() internal { + address[] memory aTokenList = _getATokenList(); + for (uint256 i = 0; i < aTokenList.length; i++) { + if ( + !(IERC20(aTokenList[i]).allowance( + address(this), + _protectionAction + ) == type(uint256).max) + ) { + IERC20(aTokenList[i]).approve( + _protectionAction, + type(uint256).max + ); + } + } + } + + function _revokeAllowance() internal { + address[] memory aTokenList = _getATokenList(); + for (uint256 i = 0; i < aTokenList.length; i++) { + if ( + !(IERC20(aTokenList[i]).allowance( + address(this), + _protectionAction + ) == 0) + ) { + IERC20(aTokenList[i]).approve(_protectionAction, 0); + } + } + } + + function _getATokenList() + internal + view + returns (address[] memory aTokenList) + { + address[] memory underlyingsList = _lendingPool.getReservesList(); + aTokenList = new address[](underlyingsList.length); + for (uint256 i = 0; i < underlyingsList.length; i++) { + aTokenList[i] = (_lendingPool.getReserveData(underlyingsList[i])) + .aTokenAddress; + } + } + + function _dsaHasProtection() internal view returns (bool) { + return + _aaveServices.taskByUsersAction(address(this), _protectionAction) != + bytes32(0); + } +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/gelato/aave-services/protection/interface.sol b/contracts/mainnet/connectors/gelato/aave-services/protection/interface.sol new file mode 100644 index 00000000..912da744 --- /dev/null +++ b/contracts/mainnet/connectors/gelato/aave-services/protection/interface.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.6; +pragma abicoder v2; + +struct ReserveData { + //stores the reserve configuration + ReserveConfigurationMap configuration; + //the liquidity index. Expressed in ray + uint128 liquidityIndex; + //variable borrow index. Expressed in ray + uint128 variableBorrowIndex; + //the current supply rate. Expressed in ray + uint128 currentLiquidityRate; + //the current variable borrow rate. Expressed in ray + uint128 currentVariableBorrowRate; + //the current stable borrow rate. Expressed in ray + uint128 currentStableBorrowRate; + uint40 lastUpdateTimestamp; + //tokens addresses + address aTokenAddress; + address stableDebtTokenAddress; + address variableDebtTokenAddress; + //address of the interest rate strategy + address interestRateStrategyAddress; + //the id of the reserve. Represents the position in the list of the active reserves + uint8 id; +} + +struct ReserveConfigurationMap { + //bit 0-15: LTV + //bit 16-31: Liq. threshold + //bit 32-47: Liq. bonus + //bit 48-55: Decimals + //bit 56: Reserve is active + //bit 57: reserve is frozen + //bit 58: borrowing is enabled + //bit 59: stable rate borrowing enabled + //bit 60-63: reserved + //bit 64-79: reserve factor + uint256 data; +} + +interface LendingPoolInterface { + function getReservesList() external view returns (address[] memory); + + function getReserveData(address asset) + external + view + returns (ReserveData memory); +} + +interface AaveServicesInterface { + function submitTask( + address _action, + bytes memory _taskData, + bool _isPermanent + ) external; + + function cancelTask(address _action) external; + + function updateTask( + address _action, + bytes memory _data, + bool _isPermanent + ) external; + + function taskByUsersAction(address _user, address _action) + external + view + returns (bytes32); +} + +interface IERC20 { + function approve(address spender, uint256 amount) external returns (bool); + + function allowance(address owner, address spender) + external + view + returns (uint256); +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/gelato/aave-services/protection/main.sol b/contracts/mainnet/connectors/gelato/aave-services/protection/main.sol new file mode 100644 index 00000000..79194c4a --- /dev/null +++ b/contracts/mainnet/connectors/gelato/aave-services/protection/main.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.7.6; +pragma abicoder v2; + +/** + * @title Aave Protection. + * @dev Protect DSA against Liquidation risk on Aave with Gelato. + */ + +import {Events} from "./events.sol"; +import {Helpers} from "./helpers.sol"; + +abstract contract GAaveProtectionResolver is Events, Helpers { + /// @dev Function for submitting a protection task + /// @param _wantedHealthFactor targeted health after protection. + /// @param _minimumHealthFactor trigger protection when current health + /// factor is below _minimumHealthFactor. + /// @param _isPermanent boolean to set a protection as permanent + function submitProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) external payable { + _submitProtection( + _wantedHealthFactor, + _minimumHealthFactor, + _isPermanent + ); + emit LogSubmitProtection( + address(this), + _protectionAction, + _wantedHealthFactor, + _minimumHealthFactor, + _isPermanent + ); + } + + /// @dev Function for modifying a protection task + /// @param _wantedHealthFactor targeted health after protection. + /// @param _minimumHealthFactor trigger protection when current health + /// factor is below _minimumHealthFactor. + /// @param _isPermanent boolean to set a protection as permanent + function updateProtection( + uint256 _wantedHealthFactor, + uint256 _minimumHealthFactor, + bool _isPermanent + ) external payable { + _updateProtection( + _wantedHealthFactor, + _minimumHealthFactor, + _isPermanent + ); + emit LogUpdateProtection( + address(this), + _protectionAction, + _wantedHealthFactor, + _minimumHealthFactor, + _isPermanent + ); + } + + /// @dev Function for cancelling a protection task + function cancelProtection() external payable { + _cancelProtection(); + emit LogCancelProtection(address(this), _protectionAction); + } + + /// @dev Function for cancelling and removing allowance + /// of aToken to _protectionAction + function cancelAndRevoke() external payable { + if (_dsaHasProtection()) _cancelProtection(); + _revokeAllowance(); + emit LogCancelAndRevoke(address(this), _protectionAction); + } +} + +contract GAaveProtectionMainnetConnector is GAaveProtectionResolver { + // solhint-disable-next-line const-name-snakecase + string public constant name = "GAaveProtectionMainnetConnector-v1"; +} \ No newline at end of file diff --git a/docs/connectors.json b/docs/connectors.json index 6979490c..bc8179a8 100644 --- a/docs/connectors.json +++ b/docs/connectors.json @@ -24,7 +24,8 @@ "WETH-A": "0x22075fa719eFb02Ca3cF298AFa9C974B7465E5D3", "REFINANCE-A": "0x6f22931423e8ffC8d51f6E5aF73118fC64b27856", "INST-A": "0x52C2C4a0db049255fF345EB9D3Fb1f555b7a924A", - "REFLEXER-A": "0xaC6dc28a6251F49Bbe5755E630107Dccde9ae2C8" + "REFLEXER-A": "0xaC6dc28a6251F49Bbe5755E630107Dccde9ae2C8", + "AAVE-PROT-A": "0x825832a5A589ed9500CaEE2aa2D2c3117218D6A9" }, "137" : { "1INCH-A": "0xC0d9210496afE9763F5d8cEb8deFfBa817232A9e", From 93daf43214cd46f21288a58e24baa398867e1303 Mon Sep 17 00:00:00 2001 From: Twin Fish Date: Thu, 7 Oct 2021 11:46:03 +0200 Subject: [PATCH 6/7] Update docs/connectors.json Co-authored-by: Thrilok kumar --- docs/connectors.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/connectors.json b/docs/connectors.json index 8a226db3..41c15a61 100644 --- a/docs/connectors.json +++ b/docs/connectors.json @@ -25,7 +25,7 @@ "REFINANCE-A": "0x6f22931423e8ffC8d51f6E5aF73118fC64b27856", "INST-A": "0x52C2C4a0db049255fF345EB9D3Fb1f555b7a924A", "REFLEXER-A": "0xaC6dc28a6251F49Bbe5755E630107Dccde9ae2C8", - "AAVE-PROT-A": "0x825832a5A589ed9500CaEE2aa2D2c3117218D6A9" + "GELATO-AAVE-A: "0x825832a5A589ed9500CaEE2aa2D2c3117218D6A9" "LIQUITY-A": "0x3643bA40B8e2bd8F77233BDB6abe38c218f31bFe", "UNISWAP-V3-A": "0x25B0c76dE86C3457b9B8b9ee3775F5a7b8D4c475", "B-COMPOUND-A": "0xa3EeFDc2de9DFA59968bEcff3E15b53E6162460f", From 2be8589d4576563fce8ff42ccb7c29b72f463f15 Mon Sep 17 00:00:00 2001 From: Twin Fish Date: Thu, 7 Oct 2021 11:46:10 +0200 Subject: [PATCH 7/7] Update docs/connectors.json Co-authored-by: Thrilok kumar --- docs/connectors.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/connectors.json b/docs/connectors.json index 41c15a61..d7fb01cb 100644 --- a/docs/connectors.json +++ b/docs/connectors.json @@ -39,7 +39,7 @@ "BASIC-A": "0x1cAF5EC802ca602E98139AD96A8f2B7BC524264E", "AAVE-CLAIM-A": "0xC7Cb1dE2721BFC0E0DA1b9D526bCdC54eF1C0eFC", "PARASWAP-A": "0xFb3a1D56eD56F046721B9aCa749895100754578b", - "AAVE-PROT-A": "0x177Bd89A1D8643C9525D2DF131C1a6C513869299" + "GELATO-AAAVE-A": "0x177Bd89A1D8643C9525D2DF131C1a6C513869299" "PARASWAP-A": "0xFb3a1D56eD56F046721B9aCa749895100754578b" }, "arbitrum" : {