-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathERC20DepositToken.sol
125 lines (103 loc) · 3.93 KB
/
ERC20DepositToken.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
122
123
124
125
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.25;
import "./DepositToken.sol";
import "./ERC20DepositTokenFactory.sol";
import "./ERC20DepositTokenImplementation.sol";
/**
* @title ERC20 Deposit Token
* @author MetaStreet Labs
*/
contract ERC20DepositToken is DepositToken {
/**************************************************************************/
/* Structures */
/**************************************************************************/
/**
* @custom:storage-location erc7201:erc20DepositToken.depositTokenStorage
*/
struct DepositTokenStorage {
/* Mapping of tick to token address */
mapping(uint128 => address) tokens;
}
/**************************************************************************/
/* State */
/**************************************************************************/
/**
* @notice Current ERC20 deposit token implementation
*/
address internal immutable _implementation;
/**
* @notice Deposit token storage slot
* @dev keccak256(abi.encode(uint256(keccak256("erc20DepositToken.depositTokenStorage")) - 1)) & ~bytes32(uint256(0xff));
*/
bytes32 private constant DEPOSIT_TOKEN_STORAGE_LOCATION =
0xc61d9ab4916a5eab6b572dc8707662b99e55e17ecdc61af8ff79465ad64ded00;
/**************************************************************************/
/* Constructor */
/**************************************************************************/
/**
* @notice ERC20DepositToken constructor
*
* @param implementation_ ERC20 deposit token implementation address
*/
constructor(address implementation_) {
_implementation = implementation_;
}
/**************************************************************************/
/* Internal Helpers */
/**************************************************************************/
/**
* @notice Get reference to ERC-7201 deposit token storage
*
* @return $ Reference to deposit token storage
*/
function _getDepositTokenStorage() private pure returns (DepositTokenStorage storage $) {
assembly {
$.slot := DEPOSIT_TOKEN_STORAGE_LOCATION
}
}
/**************************************************************************/
/* API */
/**************************************************************************/
/**
* @notice Get ERC20 Deposit Token implementation address
*
* @return ERC20 Deposit Token implementation address
*/
function getERC20DepositTokenImplementation() external view returns (address) {
return _implementation;
}
/**
* @notice Tokenize a tick
*
* @param tick Tick
*/
function _tokenize(uint128 tick) internal override returns (address) {
/* Return token if it already exists */
address tokenInstance = depositToken(tick);
if (tokenInstance != address(0)) {
emit TokenCreated(tokenInstance, _implementation, tick);
return tokenInstance;
}
/* Create proxied token */
tokenInstance = ERC20DepositTokenFactory.deploy(tick);
/* Store token instance in mapping */
_getDepositTokenStorage().tokens[tick] = tokenInstance;
emit TokenCreated(tokenInstance, _implementation, tick);
return tokenInstance;
}
/**
* @inheritdoc DepositToken
*/
function depositToken(uint128 tick) public view override returns (address) {
return _getDepositTokenStorage().tokens[tick];
}
/**
* @inheritdoc DepositToken
*/
function _onExternalTransfer(address from, address to, uint128 tick, uint256 shares) internal override {
/* No operation if token does not exist */
if (depositToken(tick) == address(0)) return;
/* Call external transfer hook */
ERC20DepositTokenImplementation(depositToken(tick)).onExternalTransfer(from, to, shares);
}
}