diff --git a/contracts/ecosystem/AaveEcosystemReserveController.sol b/contracts/ecosystem/AaveEcosystemReserveController.sol new file mode 100644 index 00000000..fd7152df --- /dev/null +++ b/contracts/ecosystem/AaveEcosystemReserveController.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import {Ownable} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/Ownable.sol'; +import {IStreamable} from './interfaces/IStreamable.sol'; +import {IAdminControlledEcosystemReserve} from './interfaces/IAdminControlledEcosystemReserve.sol'; +import {IAaveEcosystemReserveController} from './interfaces/IAaveEcosystemReserveController.sol'; +import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; + +contract AaveEcosystemReserveController is Ownable, IAaveEcosystemReserveController { + /** + * @notice Constructor. + * @param aaveGovShortTimelock The address of the Aave's governance executor, owning this contract + */ + constructor(address aaveGovShortTimelock) { + transferOwnership(aaveGovShortTimelock); + } + + /// @inheritdoc IAaveEcosystemReserveController + function approve( + address collector, + IERC20 token, + address recipient, + uint256 amount + ) external onlyOwner { + IAdminControlledEcosystemReserve(collector).approve(token, recipient, amount); + } + + /// @inheritdoc IAaveEcosystemReserveController + function transfer( + address collector, + IERC20 token, + address recipient, + uint256 amount + ) external onlyOwner { + IAdminControlledEcosystemReserve(collector).transfer(token, recipient, amount); + } + + /// @inheritdoc IAaveEcosystemReserveController + function createStream( + address collector, + address recipient, + uint256 deposit, + IERC20 tokenAddress, + uint256 startTime, + uint256 stopTime + ) external onlyOwner returns (uint256) { + return + IStreamable(collector).createStream( + recipient, + deposit, + address(tokenAddress), + startTime, + stopTime + ); + } + + /// @inheritdoc IAaveEcosystemReserveController + function withdrawFromStream( + address collector, + uint256 streamId, + uint256 funds + ) external onlyOwner returns (bool) { + return IStreamable(collector).withdrawFromStream(streamId, funds); + } + + /// @inheritdoc IAaveEcosystemReserveController + function cancelStream(address collector, uint256 streamId) external onlyOwner returns (bool) { + return IStreamable(collector).cancelStream(streamId); + } +} diff --git a/contracts/ecosystem/interfaces/IAaveEcosystemReserveController.sol b/contracts/ecosystem/interfaces/IAaveEcosystemReserveController.sol new file mode 100644 index 00000000..bd8131e7 --- /dev/null +++ b/contracts/ecosystem/interfaces/IAaveEcosystemReserveController.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; + +interface IAaveEcosystemReserveController { + /** + * @notice Proxy function for ERC20's approve(), pointing to a specific collector contract + * @param collector The collector contract with funds (Aave ecosystem reserve) + * @param token The asset address + * @param recipient Allowance's recipient + * @param amount Allowance to approve + **/ + function approve( + address collector, + IERC20 token, + address recipient, + uint256 amount + ) external; + + /** + * @notice Proxy function for ERC20's transfer(), pointing to a specific collector contract + * @param collector The collector contract with funds (Aave ecosystem reserve) + * @param token The asset address + * @param recipient Transfer's recipient + * @param amount Amount to transfer + **/ + function transfer( + address collector, + IERC20 token, + address recipient, + uint256 amount + ) external; + + /** + * @notice Proxy function to create a stream of token on a specific collector contract + * @param collector The collector contract with funds (Aave ecosystem reserve) + * @param recipient The recipient of the stream of token + * @param deposit Total amount to be streamed + * @param tokenAddress The ERC20 token to use as streaming asset + * @param startTime The unix timestamp for when the stream starts + * @param stopTime The unix timestamp for when the stream stops + * @return uint256 The stream id created + **/ + function createStream( + address collector, + address recipient, + uint256 deposit, + IERC20 tokenAddress, + uint256 startTime, + uint256 stopTime + ) external returns (uint256); + + /** + * @notice Proxy function to withdraw from a stream of token on a specific collector contract + * @param collector The collector contract with funds (Aave ecosystem reserve) + * @param streamId The id of the stream to withdraw tokens from + * @param funds Amount to withdraw + * @return bool If the withdrawal finished properly + **/ + function withdrawFromStream( + address collector, + uint256 streamId, + uint256 funds + ) external returns (bool); + + /** + * @notice Proxy function to cancel a stream of token on a specific collector contract + * @param collector The collector contract with funds (Aave ecosystem reserve) + * @param streamId The id of the stream to cancel + * @return bool If the cancellation happened correctly + **/ + function cancelStream(address collector, uint256 streamId) external returns (bool); +}