forked from aave-dao/aave-v3-origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStataTokenV2.sol
121 lines (107 loc) · 4.19 KB
/
StataTokenV2.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import {ERC20Upgradeable, ERC20PermitUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol';
import {IERC20Metadata} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
import {PausableUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol';
import {IRescuable, Rescuable} from 'solidity-utils/contracts/utils/Rescuable.sol';
import {IRescuableBase, RescuableBase} from 'solidity-utils/contracts/utils/RescuableBase.sol';
import {IERC20Permit} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol';
import {IACLManager} from '../../../contracts/interfaces/IACLManager.sol';
import {ERC4626Upgradeable, ERC4626StataTokenUpgradeable, IPool, Math, IERC20} from './ERC4626StataTokenUpgradeable.sol';
import {ERC20AaveLMUpgradeable, IRewardsController} from './ERC20AaveLMUpgradeable.sol';
import {IStataTokenV2} from './interfaces/IStataTokenV2.sol';
import {IAToken} from './interfaces/IAToken.sol';
/**
* @title StataTokenV2
* @notice A 4626 Vault which wrapps aTokens in order to translate the rebasing nature of yield accrual into a non-rebasing value accrual.
* @author BGD labs
*/
contract StataTokenV2 is
ERC20PermitUpgradeable,
ERC20AaveLMUpgradeable,
ERC4626StataTokenUpgradeable,
PausableUpgradeable,
Rescuable,
IStataTokenV2
{
using Math for uint256;
constructor(
IPool pool,
IRewardsController rewardsController
) ERC20AaveLMUpgradeable(rewardsController) ERC4626StataTokenUpgradeable(pool) {
_disableInitializers();
}
modifier onlyPauseGuardian() {
if (!canPause(_msgSender())) revert OnlyPauseGuardian(_msgSender());
_;
}
function initialize(
address aToken,
string calldata staticATokenName,
string calldata staticATokenSymbol
) external initializer {
__ERC20_init(staticATokenName, staticATokenSymbol);
__ERC20Permit_init(staticATokenName);
__ERC20AaveLM_init(aToken);
__ERC4626StataToken_init(aToken);
__Pausable_init();
}
///@inheritdoc IStataTokenV2
function setPaused(bool paused) external onlyPauseGuardian {
if (paused) _pause();
else _unpause();
}
/// @inheritdoc Rescuable
function whoCanRescue() public view override returns (address) {
return POOL_ADDRESSES_PROVIDER.getACLAdmin();
}
/// @inheritdoc IRescuableBase
function maxRescue(
address asset
) public view override(IRescuableBase, RescuableBase) returns (uint256) {
address cachedAToken = aToken();
if (asset == cachedAToken) {
uint256 requiredBacking = _convertToAssets(totalSupply(), Math.Rounding.Ceil);
uint256 balance = IERC20(cachedAToken).balanceOf(address(this));
return balance > requiredBacking ? balance - requiredBacking : 0;
}
return type(uint256).max;
}
///@inheritdoc IStataTokenV2
function canPause(address actor) public view returns (bool) {
return IACLManager(POOL_ADDRESSES_PROVIDER.getACLManager()).isEmergencyAdmin(actor);
}
///@inheritdoc IERC20Permit
function nonces(
address owner
) public view virtual override(ERC20PermitUpgradeable, IERC20Permit) returns (uint256) {
return super.nonces(owner);
}
///@inheritdoc IERC20Metadata
function decimals()
public
view
override(IERC20Metadata, ERC20Upgradeable, ERC4626Upgradeable)
returns (uint8)
{
/// @notice The initialization of ERC4626Upgradeable already assures that decimal are
/// the same as the underlying asset of the StataTokenV2, e.g. decimals of WETH for stataWETH
return ERC4626Upgradeable.decimals();
}
function _claimRewardsOnBehalf(
address onBehalfOf,
address receiver,
address[] memory rewards
) internal virtual override whenNotPaused {
super._claimRewardsOnBehalf(onBehalfOf, receiver, rewards);
}
// @notice to merge inheritance with ERC20AaveLMUpgradeable.sol properly we put
// `whenNotPaused` here instead of using ERC20PausableUpgradeable
function _update(
address from,
address to,
uint256 amount
) internal virtual override(ERC20AaveLMUpgradeable, ERC20Upgradeable) whenNotPaused {
ERC20AaveLMUpgradeable._update(from, to, amount);
}
}