Skip to content

Commit 9b137c8

Browse files
authored
chore(honey): move preview functions to reader contract
This also allow to fix UX issues that emerged from the frontend.
1 parent fdb0d80 commit 9b137c8

File tree

8 files changed

+572
-80
lines changed

8 files changed

+572
-80
lines changed

script/base/actions/ValidateHoneyUpgrade.s.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ contract ValidateHoneyUpgrade is Script {
2828
Upgrades.validateUpgrade("CollateralVault.sol", options);
2929
console2.log("CollateralVault can be upgraded successfully.");
3030

31+
// check HoneyFactoryReader safe upgrade
32+
options.referenceContract = "HoneyFactoryReader_V0.sol:HoneyFactoryReader_V0";
33+
Upgrades.validateUpgrade("HoneyFactoryReader.sol", options);
34+
console2.log("HoneyFactoryReader can be upgraded successfully.");
35+
3136
vm.stopBroadcast();
3237
}
3338
}

script/honey/HoneyAddresses.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ address constant HONEY_FACTORY_ADDRESS = 0xA4aFef880F5cE1f63c9fb48F661E27F8B4216
66
address constant HONEY_FACTORY_READER_ADDRESS = 0x285e147060CDc5ba902786d3A471224ee6cE0F91;
77
// HoneyFactory and CollateralVault new implementation, compiled with `deploy` profile
88
address constant HONEY_FACTORY_IMPL = 0x3Ba6452ED6C57f4E1A6334E0C3b810c481AdaC64;
9-
address constant HONEY_FACTORY_READER_IMPL = 0x8101047E260AFbe747D12498e7901dCB9E3267Cb;
9+
address constant HONEY_FACTORY_READER_IMPL = 0x5603fC37e35Ec730E2305e865CEC780831cF424A;
1010
address constant COLLATERAL_VAULT_IMPL = 0xb1bBa664fdAdeC06d57Ff49630Cb051f1e0EF483;
11-
address constant HONEY_FACTORY_PYTH_WRAPPER_ADDRESS = 0x1Ba9636b823D3aB50CA57819434B7f4C0c60E09B;
11+
address constant HONEY_FACTORY_PYTH_WRAPPER_ADDRESS = 0x4b7cb1c197f8EE4d309866B16C2c12E3B4E7E606;

src/honey/HoneyFactoryPythWrapper.sol

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -117,48 +117,6 @@ contract HoneyFactoryPythWrapper is IHoneyFactoryPythWrapper, IHoneyErrors {
117117
_refundAnyLeftover(asset);
118118
}
119119

120-
/// @inheritdoc IHoneyFactoryPythWrapper
121-
/// @dev Implementation is copied 1:1 from HoneyFactory to not edit the original contract.
122-
function isBasketModeEnabled(bool isMint, uint256[] memory prices) public view returns (bool basketMode) {
123-
IHoneyFactory factory_ = IHoneyFactory(factory);
124-
VaultAdmin v = VaultAdmin(factory);
125-
uint256 registeredAssetsLen = v.numRegisteredAssets();
126-
127-
if (factory_.forcedBasketMode()) return true;
128-
129-
for (uint256 i = 0; i < registeredAssetsLen; i++) {
130-
address asset = v.registeredAssets(i);
131-
bool isPegged_ = isPegged(asset, prices[i]);
132-
133-
if (isMint) {
134-
if (isPegged_ && !v.isBadCollateralAsset(asset)) {
135-
// Basket mode should be disabled. It means there is a good collateral.
136-
return false;
137-
}
138-
} else if (!isPegged_) {
139-
// If the not pegged asset is a bad collateral and its vault doesn't have shares
140-
// we can ignore it because it means it has been fully liquidated.
141-
uint256 sharesWithoutFees = v.vaults(asset).balanceOf(factory) - v.collectedAssetFees(asset);
142-
bool usedAsCollateral = sharesWithoutFees > 0;
143-
144-
if (!usedAsCollateral) {
145-
continue;
146-
}
147-
return true;
148-
}
149-
}
150-
151-
// When is mint and there is no asset that disable basket mode, return true.
152-
// When is redeem and there is no asset that enable basket mode, return false.
153-
return isMint ? true : false;
154-
}
155-
156-
/// @inheritdoc IHoneyFactoryPythWrapper
157-
function isPegged(address asset, uint256 price) public view returns (bool) {
158-
return (1e18 - IHoneyFactory(factory).lowerPegOffsets(asset) <= price)
159-
&& (price <= 1e18 + IHoneyFactory(factory).upperPegOffsets(asset));
160-
}
161-
162120
///////// INTERNAL /////////
163121

164122
function _updatePyth(bytes[] memory updateData) internal {

src/honey/HoneyFactoryReader.sol

Lines changed: 189 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ contract HoneyFactoryReader is AccessControlUpgradeable, UUPSUpgradeable, IHoney
2020
/// @notice The HoneyFactory contract.
2121
HoneyFactory public honeyFactory;
2222

23+
/// @custom:oz-upgrades-unsafe-allow constructor
2324
constructor() {
2425
_disableInitializers();
2526
}
@@ -41,11 +42,185 @@ contract HoneyFactoryReader is AccessControlUpgradeable, UUPSUpgradeable, IHoney
4142

4243
/// @inheritdoc IHoneyFactoryReader
4344
/// @dev `asset` param is ignored if running in basket mode.
44-
function previewMintCollaterals(address asset, uint256 honey) public view returns (uint256[] memory amounts) {
45+
function previewMintCollaterals(address asset, uint256 honey) external view returns (uint256[] memory amounts) {
46+
bool basketMode = honeyFactory.isBasketModeEnabled(true);
47+
48+
amounts = _previewMintCollaterals(asset, honey, basketMode);
49+
}
50+
51+
/// @inheritdoc IHoneyFactoryReader
52+
/// @dev `asset` param is ignored if running in basket mode.
53+
function previewMintCollateralsWithPrices(
54+
address asset,
55+
uint256 honey,
56+
uint256[] memory prices
57+
)
58+
external
59+
view
60+
returns (uint256[] memory amounts)
61+
{
62+
bool basketMode = isBasketModeEnabledWithPrices(true, prices);
63+
64+
amounts = _previewMintCollaterals(asset, honey, basketMode);
65+
}
66+
67+
/// @inheritdoc IHoneyFactoryReader
68+
function previewMintHoney(
69+
address asset,
70+
uint256 amount
71+
)
72+
external
73+
view
74+
returns (uint256[] memory collaterals, uint256 honey)
75+
{
76+
bool basketMode = honeyFactory.isBasketModeEnabled(true);
77+
78+
(collaterals, honey) = _previewMintHoney(asset, amount, basketMode);
79+
}
80+
81+
/// @inheritdoc IHoneyFactoryReader
82+
function previewMintHoneyWithPrices(
83+
address asset,
84+
uint256 amount,
85+
uint256[] memory prices
86+
)
87+
external
88+
view
89+
returns (uint256[] memory collaterals, uint256 honey)
90+
{
91+
bool basketMode = isBasketModeEnabledWithPrices(true, prices);
92+
93+
(collaterals, honey) = _previewMintHoney(asset, amount, basketMode);
94+
}
95+
96+
/// @inheritdoc IHoneyFactoryReader
97+
/// @dev `asset` param is ignored if running in basket mode.
98+
function previewRedeemCollaterals(
99+
address asset,
100+
uint256 honey
101+
)
102+
external
103+
view
104+
returns (uint256[] memory collaterals)
105+
{
106+
bool basketMode = honeyFactory.isBasketModeEnabled(false);
107+
108+
collaterals = _previewRedeemCollaterals(asset, honey, basketMode);
109+
}
110+
111+
/// @inheritdoc IHoneyFactoryReader
112+
/// @dev `asset` param is ignored if running in basket mode.
113+
function previewRedeemCollateralsWithPrices(
114+
address asset,
115+
uint256 honey,
116+
uint256[] memory prices
117+
)
118+
external
119+
view
120+
returns (uint256[] memory collaterals)
121+
{
122+
bool basketMode = isBasketModeEnabledWithPrices(false, prices);
123+
124+
collaterals = _previewRedeemCollaterals(asset, honey, basketMode);
125+
}
126+
127+
/// @inheritdoc IHoneyFactoryReader
128+
/// @dev If the basket mode is enabled, the required Honey amount will provide also other collaterals beside
129+
/// required `amount` of `asset`.
130+
function previewRedeemHoney(
131+
address asset,
132+
uint256 amount
133+
)
134+
external
135+
view
136+
returns (uint256[] memory collaterals, uint256 honey)
137+
{
138+
bool basketMode = honeyFactory.isBasketModeEnabled(false);
139+
140+
(collaterals, honey) = _previewRedeemHoney(asset, amount, basketMode);
141+
}
142+
143+
/// @inheritdoc IHoneyFactoryReader
144+
/// @dev If the basket mode is enabled, the required Honey amount will provide also other collaterals beside
145+
/// required `amount` of `asset`.
146+
function previewRedeemHoneyWithPrices(
147+
address asset,
148+
uint256 amount,
149+
uint256[] memory prices
150+
)
151+
external
152+
view
153+
returns (uint256[] memory collaterals, uint256 honey)
154+
{
155+
bool basketMode = isBasketModeEnabledWithPrices(false, prices);
156+
157+
(collaterals, honey) = _previewRedeemHoney(asset, amount, basketMode);
158+
}
159+
160+
/// @inheritdoc IHoneyFactoryReader
161+
/// @dev Implementation is copied 1:1 from HoneyFactory to not edit the original contract.
162+
function isBasketModeEnabledWithPrices(
163+
bool isMint,
164+
uint256[] memory prices
165+
)
166+
public
167+
view
168+
returns (bool basketMode)
169+
{
170+
uint256 registeredAssetsLen = honeyFactory.numRegisteredAssets();
171+
172+
if (honeyFactory.forcedBasketMode()) return true;
173+
174+
for (uint256 i = 0; i < registeredAssetsLen; i++) {
175+
address asset = honeyFactory.registeredAssets(i);
176+
bool isPegged_ = isPeggedWithPrice(asset, prices[i]);
177+
178+
if (isMint) {
179+
if (isPegged_ && !honeyFactory.isBadCollateralAsset(asset)) {
180+
// Basket mode should be disabled. It means there is a good collateral.
181+
return false;
182+
}
183+
} else if (!isPegged_) {
184+
// If the not pegged asset is a bad collateral and its vault doesn't have shares
185+
// we can ignore it because it means it has been fully liquidated.
186+
uint256 sharesWithoutFees = honeyFactory.vaults(asset).balanceOf(address(honeyFactory))
187+
- honeyFactory.collectedAssetFees(asset);
188+
bool usedAsCollateral = sharesWithoutFees > 0;
189+
190+
if (!usedAsCollateral) {
191+
continue;
192+
}
193+
return true;
194+
}
195+
}
196+
197+
// When is mint and there is no asset that disable basket mode, return true.
198+
// When is redeem and there is no asset that enable basket mode, return false.
199+
return isMint ? true : false;
200+
}
201+
202+
/// @inheritdoc IHoneyFactoryReader
203+
function isPeggedWithPrice(address asset, uint256 price) public view returns (bool) {
204+
return (1e18 - honeyFactory.lowerPegOffsets(asset) <= price)
205+
&& (price <= 1e18 + honeyFactory.upperPegOffsets(asset));
206+
}
207+
208+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
209+
/* INTERNAL FUNCTIONS */
210+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
211+
212+
function _previewMintCollaterals(
213+
address asset,
214+
uint256 honey,
215+
bool basketMode
216+
)
217+
internal
218+
view
219+
returns (uint256[] memory amounts)
220+
{
45221
(address[] memory collaterals, uint256 num) = _getCollaterals();
46222
amounts = new uint256[](num);
47223
uint256[] memory weights = honeyFactory.getWeights();
48-
bool basketMode = honeyFactory.isBasketModeEnabled(true);
49224
for (uint256 i = 0; i < num; i++) {
50225
if (!basketMode && collaterals[i] != asset) {
51226
continue;
@@ -66,37 +241,34 @@ contract HoneyFactoryReader is AccessControlUpgradeable, UUPSUpgradeable, IHoney
66241
}
67242
}
68243

69-
/// @inheritdoc IHoneyFactoryReader
70-
function previewMintHoney(
244+
function _previewMintHoney(
71245
address asset,
72-
uint256 amount
246+
uint256 amount,
247+
bool basketMode
73248
)
74-
external
249+
internal
75250
view
76251
returns (uint256[] memory collaterals, uint256 honey)
77252
{
78-
bool basketMode = honeyFactory.isBasketModeEnabled(true);
79253
collaterals = _getWeightedCollaterals(asset, amount, basketMode);
80254
(address[] memory assets, uint256 num) = _getCollaterals();
81255
for (uint256 i = 0; i < num; i++) {
82256
honey += _previewMint(assets[i], collaterals[i]);
83257
}
84258
}
85259

86-
/// @inheritdoc IHoneyFactoryReader
87-
/// @dev `asset` param is ignored if running in basket mode.
88-
function previewRedeemCollaterals(
260+
function _previewRedeemCollaterals(
89261
address asset,
90-
uint256 honey
262+
uint256 honey,
263+
bool basketMode
91264
)
92-
external
265+
internal
93266
view
94267
returns (uint256[] memory collaterals)
95268
{
96269
(address[] memory assets, uint256 num) = _getCollaterals();
97270
collaterals = new uint256[](num);
98271

99-
bool basketMode = honeyFactory.isBasketModeEnabled(false);
100272
if (!basketMode) {
101273
(uint256 refAssetIndex,) = _getIndexOfAsset(assets, num, asset);
102274
collaterals[refAssetIndex] = _previewRedeem(asset, honey);
@@ -110,29 +282,22 @@ contract HoneyFactoryReader is AccessControlUpgradeable, UUPSUpgradeable, IHoney
110282
}
111283
}
112284

113-
/// @inheritdoc IHoneyFactoryReader
114-
/// @dev If the basket mode is enabled, the required Honey amount will provide also other collaterals beside
115-
/// required `amount` of `asset`.
116-
function previewRedeemHoney(
285+
function _previewRedeemHoney(
117286
address asset,
118-
uint256 amount
287+
uint256 amount,
288+
bool basketMode
119289
)
120-
external
290+
internal
121291
view
122292
returns (uint256[] memory collaterals, uint256 honey)
123293
{
124-
bool basketMode = honeyFactory.isBasketModeEnabled(false);
125294
collaterals = _getWeightedCollaterals(asset, amount, basketMode);
126295
(address[] memory assets, uint256 num) = _getCollaterals();
127296
for (uint256 i = 0; i < num; i++) {
128297
honey += _previewHoneyToRedeem(assets[i], collaterals[i]);
129298
}
130299
}
131300

132-
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
133-
/* INTERNAL FUNCTIONS */
134-
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
135-
136301
/// @notice Get the amount of Honey that can be minted with the given ERC20.
137302
/// @param asset The ERC20 to mint with.
138303
/// @param amount The amount of ERC20 to mint with.

src/honey/IHoneyFactoryPythWrapper.sol

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,4 @@ interface IHoneyFactoryPythWrapper {
6969
/// @param asset The ERC20 asset to recapitalize.
7070
/// @param amount The amount provided.
7171
function recapitalize(bytes[] calldata updateData, address asset, uint256 amount) external payable;
72-
73-
/// @notice HoneyFactory isBasketModeEnabled with externally provided price.
74-
/// @param isMint True if checking basket mode for minting.
75-
/// @param prices The prices assumed to be valid.
76-
function isBasketModeEnabled(bool isMint, uint256[] memory prices) external returns (bool basketMode);
77-
78-
/// @notice HoneyFactory isPegged with externally provided price.
79-
/// @param asset The asset to check.
80-
/// @param price The price assumed to be valid.
81-
/// @return true if the asset is pegged.
82-
function isPegged(address asset, uint256 price) external returns (bool);
8372
}

0 commit comments

Comments
 (0)