Branch data Line data Source code
1 : : // SPDX-License-Identifier: BUSL-1.1
2 : : pragma solidity ^0.8.10;
3 : :
4 : : import {IStakedToken} from '../interfaces/IStakedToken.sol';
5 : : import {IStakedTokenTransferStrategy} from '../interfaces/IStakedTokenTransferStrategy.sol';
6 : : import {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol';
7 : : import {TransferStrategyBase} from './TransferStrategyBase.sol';
8 : : import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol';
9 : : import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
10 : :
11 : : /**
12 : : * @title StakedTokenTransferStrategy
13 : : * @notice Transfer strategy that stakes the rewards into a staking contract and transfers the staking contract token.
14 : : * The underlying token must be transferred to this contract to be able to stake it on demand.
15 : : * @author Aave
16 : : **/
17 : : contract StakedTokenTransferStrategy is TransferStrategyBase, IStakedTokenTransferStrategy {
18 : : using GPv2SafeERC20 for IERC20;
19 : :
20 : : IStakedToken internal immutable STAKE_CONTRACT;
21 : : address internal immutable UNDERLYING_TOKEN;
22 : :
23 : : constructor(
24 : : address incentivesController,
25 : : address rewardsAdmin,
26 : : IStakedToken stakeToken
27 : : ) TransferStrategyBase(incentivesController, rewardsAdmin) {
28 : 0 : STAKE_CONTRACT = stakeToken;
29 : 0 : UNDERLYING_TOKEN = STAKE_CONTRACT.STAKED_TOKEN();
30 : :
31 : 0 : IERC20(UNDERLYING_TOKEN).approve(address(STAKE_CONTRACT), 0);
32 : 0 : IERC20(UNDERLYING_TOKEN).approve(address(STAKE_CONTRACT), type(uint256).max);
33 : : }
34 : :
35 : : /// @inheritdoc TransferStrategyBase
36 : : function performTransfer(
37 : : address to,
38 : : address reward,
39 : : uint256 amount
40 : : )
41 : : external
42 : : override(TransferStrategyBase, ITransferStrategyBase)
43 : : onlyIncentivesController
44 : : returns (bool)
45 : : {
46 : 1 : require(reward == address(STAKE_CONTRACT), 'REWARD_TOKEN_NOT_STAKE_CONTRACT');
47 : :
48 : 1 : STAKE_CONTRACT.stake(to, amount);
49 : :
50 : 1 : return true;
51 : : }
52 : :
53 : : /// @inheritdoc IStakedTokenTransferStrategy
54 : : function renewApproval() external onlyRewardsAdmin {
55 : 1 : IERC20(UNDERLYING_TOKEN).approve(address(STAKE_CONTRACT), 0);
56 : 1 : IERC20(UNDERLYING_TOKEN).approve(address(STAKE_CONTRACT), type(uint256).max);
57 : : }
58 : :
59 : : /// @inheritdoc IStakedTokenTransferStrategy
60 : : function dropApproval() external onlyRewardsAdmin {
61 : 1 : IERC20(UNDERLYING_TOKEN).approve(address(STAKE_CONTRACT), 0);
62 : : }
63 : :
64 : : /// @inheritdoc IStakedTokenTransferStrategy
65 : : function getStakeContract() external view returns (address) {
66 : 1 : return address(STAKE_CONTRACT);
67 : : }
68 : :
69 : : /// @inheritdoc IStakedTokenTransferStrategy
70 : : function getUnderlyingToken() external view returns (address) {
71 : 1 : return UNDERLYING_TOKEN;
72 : : }
73 : : }
|