-
Notifications
You must be signed in to change notification settings - Fork 45
/
StataTokenFactory.sol
95 lines (82 loc) · 3.53 KB
/
StataTokenFactory.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
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.10;
import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol';
import {ITransparentProxyFactory, ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol';
import {Initializable} from 'solidity-utils/contracts/transparent-proxy/Initializable.sol';
import {IPool, DataTypes} from '../../../contracts/interfaces/IPool.sol';
import {StataTokenV2} from './StataTokenV2.sol';
import {IStataTokenFactory} from './interfaces/IStataTokenFactory.sol';
/**
* @title StataTokenFactory
* @notice Factory contract that keeps track of all deployed StataTokens for a specified pool.
* This registry also acts as a factory, allowing to deploy new StataTokens on demand.
* There can only be one StataToken per underlying on the registry at any time.
* @author BGD labs
*/
contract StataTokenFactory is Initializable, IStataTokenFactory {
///@inheritdoc IStataTokenFactory
IPool public immutable POOL;
///@inheritdoc IStataTokenFactory
address public immutable PROXY_ADMIN;
///@inheritdoc IStataTokenFactory
ITransparentProxyFactory public immutable TRANSPARENT_PROXY_FACTORY;
///@inheritdoc IStataTokenFactory
address public immutable STATA_TOKEN_IMPL;
mapping(address => address) internal _underlyingToStataToken;
address[] internal _stataTokens;
event StataTokenCreated(address indexed stataToken, address indexed underlying);
constructor(
IPool pool,
address proxyAdmin,
ITransparentProxyFactory transparentProxyFactory,
address stataTokenImpl
) {
POOL = pool;
PROXY_ADMIN = proxyAdmin;
TRANSPARENT_PROXY_FACTORY = transparentProxyFactory;
STATA_TOKEN_IMPL = stataTokenImpl;
}
function initialize() external initializer {}
///@inheritdoc IStataTokenFactory
function createStataTokens(address[] memory underlyings) external returns (address[] memory) {
address[] memory stataTokens = new address[](underlyings.length);
for (uint256 i = 0; i < underlyings.length; i++) {
address cachedStataToken = _underlyingToStataToken[underlyings[i]];
if (cachedStataToken == address(0)) {
DataTypes.ReserveDataLegacy memory reserveData = POOL.getReserveData(underlyings[i]);
if (reserveData.aTokenAddress == address(0))
revert NotListedUnderlying(reserveData.aTokenAddress);
bytes memory symbol = abi.encodePacked(
'w',
IERC20Metadata(reserveData.aTokenAddress).symbol()
);
address stataToken = TRANSPARENT_PROXY_FACTORY.createDeterministic(
STATA_TOKEN_IMPL,
ProxyAdmin(PROXY_ADMIN),
abi.encodeWithSelector(
StataTokenV2.initialize.selector,
reserveData.aTokenAddress,
string(abi.encodePacked('Wrapped ', IERC20Metadata(reserveData.aTokenAddress).name())),
string(symbol)
),
bytes32(uint256(uint160(underlyings[i])))
);
_underlyingToStataToken[underlyings[i]] = stataToken;
stataTokens[i] = stataToken;
_stataTokens.push(stataToken);
emit StataTokenCreated(stataToken, underlyings[i]);
} else {
stataTokens[i] = cachedStataToken;
}
}
return stataTokens;
}
///@inheritdoc IStataTokenFactory
function getStataTokens() external view returns (address[] memory) {
return _stataTokens;
}
///@inheritdoc IStataTokenFactory
function getStataToken(address underlying) external view returns (address) {
return _underlyingToStataToken[underlying];
}
}