-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathFactory.sol
More file actions
178 lines (154 loc) · 6.6 KB
/
Factory.sol
File metadata and controls
178 lines (154 loc) · 6.6 KB
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.13;
import {BoringOwnable} from "boringsolidity/BoringOwnable.sol";
import {Bytes32AddressLib} from "solmate/utils/Bytes32AddressLib.sol";
import {Gate} from "./Gate.sol";
import {NegativeYieldToken} from "./NegativeYieldToken.sol";
import {PerpetualYieldToken} from "./PerpetualYieldToken.sol";
contract Factory is BoringOwnable {
/// -----------------------------------------------------------------------
/// Library usage
/// -----------------------------------------------------------------------
using Bytes32AddressLib for address;
using Bytes32AddressLib for bytes32;
/// -----------------------------------------------------------------------
/// Errors
/// -----------------------------------------------------------------------
error Error_ProtocolFeeRecipientIsZero();
/// -----------------------------------------------------------------------
/// Events
/// -----------------------------------------------------------------------
event SetProtocolFee(ProtocolFeeInfo protocolFeeInfo_);
event DeployYieldTokenPair(
Gate indexed gate,
address indexed vault,
NegativeYieldToken nyt,
PerpetualYieldToken pyt
);
/// -----------------------------------------------------------------------
/// Storage variables
/// -----------------------------------------------------------------------
struct ProtocolFeeInfo {
uint8 fee; // each increment represents 0.1%, so max is 25.5%
address recipient;
}
/// @notice The protocol fee and the fee recipient address.
ProtocolFeeInfo public protocolFeeInfo;
/// -----------------------------------------------------------------------
/// Constructor
/// -----------------------------------------------------------------------
constructor(ProtocolFeeInfo memory protocolFeeInfo_) {
if (
protocolFeeInfo_.fee != 0 &&
protocolFeeInfo_.recipient == address(0)
) {
revert Error_ProtocolFeeRecipientIsZero();
}
protocolFeeInfo = protocolFeeInfo_;
emit SetProtocolFee(protocolFeeInfo_);
}
/// -----------------------------------------------------------------------
/// User actions
/// -----------------------------------------------------------------------
/// @notice Deploys the NegativeYieldToken and PerpetualYieldToken associated with a vault.
/// @dev Will revert if they have already been deployed.
/// @param gate The gate that will use the NYT and PYT
/// @param vault The vault to deploy NYT and PYT for
/// @return nyt The deployed NegativeYieldToken
/// @return pyt The deployed PerpetualYieldToken
function deployYieldTokenPair(Gate gate, address vault)
public
virtual
returns (NegativeYieldToken nyt, PerpetualYieldToken pyt)
{
// Use the CREATE2 opcode to deploy new NegativeYieldToken and PerpetualYieldToken contracts.
// This will revert if the contracts have already been deployed,
// as the salt & bytecode hash would be the same and we can't deploy with it twice.
nyt = new NegativeYieldToken{salt: bytes32(0)}(gate, vault);
pyt = new PerpetualYieldToken{salt: bytes32(0)}(gate, vault);
emit DeployYieldTokenPair(gate, vault, nyt, pyt);
}
/// -----------------------------------------------------------------------
/// Getters
/// -----------------------------------------------------------------------
/// @notice Returns the NegativeYieldToken associated with a gate & vault pair.
/// @dev Returns non-zero value even if the contract hasn't been deployed yet.
/// @param gate The gate to query
/// @param vault The vault to query
/// @return The NegativeYieldToken address
function getNegativeYieldToken(Gate gate, address vault)
public
view
virtual
returns (NegativeYieldToken)
{
return
NegativeYieldToken(_computeYieldTokenAddress(gate, vault, false));
}
/// @notice Returns the PerpetualYieldToken associated with a gate & vault pair.
/// @dev Returns non-zero value even if the contract hasn't been deployed yet.
/// @param gate The gate to query
/// @param vault The vault to query
/// @return The PerpetualYieldToken address
function getPerpetualYieldToken(Gate gate, address vault)
public
view
virtual
returns (PerpetualYieldToken)
{
return
PerpetualYieldToken(_computeYieldTokenAddress(gate, vault, true));
}
/// -----------------------------------------------------------------------
/// Owner functions
/// -----------------------------------------------------------------------
/// @notice Updates the protocol fee and/or the protocol fee recipient.
/// Only callable by the owner.
/// @param protocolFeeInfo_ The new protocol fee info
function ownerSetProtocolFee(ProtocolFeeInfo calldata protocolFeeInfo_)
external
virtual
onlyOwner
{
if (
protocolFeeInfo_.fee != 0 &&
protocolFeeInfo_.recipient == address(0)
) {
revert Error_ProtocolFeeRecipientIsZero();
}
protocolFeeInfo = protocolFeeInfo_;
emit SetProtocolFee(protocolFeeInfo_);
}
/// -----------------------------------------------------------------------
/// Internal utilities
/// -----------------------------------------------------------------------
/// @dev Computes the address of PYTs and NYTs using CREATE2.
function _computeYieldTokenAddress(
Gate gate,
address vault,
bool isPerpetualYieldToken
) internal view virtual returns (address) {
return
keccak256(
abi.encodePacked(
// Prefix:
bytes1(0xFF),
// Creator:
address(this),
// Salt:
bytes32(0),
// Bytecode hash:
keccak256(
abi.encodePacked(
// Deployment bytecode:
isPerpetualYieldToken
? type(PerpetualYieldToken).creationCode
: type(NegativeYieldToken).creationCode,
// Constructor arguments:
abi.encode(gate, vault)
)
)
)
).fromLast20Bytes(); // Convert the CREATE2 hash into an address.
}
}