Skip to content

Commit

Permalink
feat: bunker mode for vaults
Browse files Browse the repository at this point in the history
  • Loading branch information
folkyatina committed Nov 27, 2024
1 parent 803199c commit 2cfd7a6
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 14 deletions.
3 changes: 2 additions & 1 deletion contracts/0.8.25/Accounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ contract Accounting is VaultHub {
update.postTotalPooledEther,
_pre.totalShares,
_pre.totalPooledEther,
update.sharesToMintAsFees
update.sharesToMintAsFees,
_report.isBunkerMode
);
}

Expand Down
29 changes: 18 additions & 11 deletions contracts/0.8.25/vaults/VaultHub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ abstract contract VaultHub is AccessControlEnumerableUpgradeable {
uint256 _postTotalPooledEther,
uint256 _preTotalShares,
uint256 _preTotalPooledEther,
uint256 _sharesToMintAsFees
uint256 _sharesToMintAsFees,
bool _isBunkerMode
) internal view returns (uint256[] memory lockedEther, uint256[] memory treasuryFeeShares) {
/// HERE WILL BE ACCOUNTING DRAGONS

Expand Down Expand Up @@ -348,9 +349,16 @@ abstract contract VaultHub is AccessControlEnumerableUpgradeable {
);
}

uint256 totalMintedShares = socket.sharesMinted + treasuryFeeShares[i];
uint256 mintedStETH = (totalMintedShares * _postTotalPooledEther) / _postTotalShares; //TODO: check rounding
lockedEther[i] = (mintedStETH * BPS_BASE) / (BPS_BASE - socket.reserveRatio);
if (!_isBunkerMode) {
uint256 postSharesMinted = socket.sharesMinted + treasuryFeeShares[i];
uint256 inStETH = (postSharesMinted * _postTotalPooledEther) / _postTotalShares;
lockedEther[i] = (inStETH * BPS_BASE) / (BPS_BASE - socket.reserveRatio);
} else {
// if bunker mode is enabled, the ether does not unlock, but fees accrues
uint256 treasuryFee = (treasuryFeeShares[i] * _postTotalPooledEther) / _postTotalShares;
uint256 treasuryFeePlusReserve = (treasuryFee * BPS_BASE) / (BPS_BASE - socket.reserveRatio);
lockedEther[i] = socket.vault.locked() + treasuryFeePlusReserve;
}
}
}

Expand All @@ -372,17 +380,16 @@ abstract contract VaultHub is AccessControlEnumerableUpgradeable {
// Lido curated validators could earn if vault's ETH was staked in Lido
// itself and minted as stETH shares
//
// treasuryFeeShares = value * lidoGrossAPR * treasuryFeeRate / preShareRate
// treasuryFeeShares = chargeableValue * lidoGrossAPR * treasuryFeeRate / preShareRate
// lidoGrossAPR = postShareRateWithoutFees / preShareRate - 1
// = value * (postShareRateWithoutFees / preShareRate - 1) * treasuryFeeRate / preShareRate
// = chargeableValue * (postShareRateWithoutFees / preShareRate - 1) * treasuryFeeRate / preShareRate

// TODO: optimize potential rewards calculation
uint256 potentialRewards = ((chargeableValue * (_postTotalPooledEther * _preTotalShares)) /
(_postTotalSharesNoFees * _preTotalPooledEther) -
chargeableValue);
uint256 treasuryFee = (potentialRewards * _socket.treasuryFeeBP) / BPS_BASE;
uint256 potentialRewards = chargeableValue *
((_postTotalPooledEther * _preTotalShares) / (_postTotalSharesNoFees * _preTotalPooledEther) - 1);

treasuryFeeShares = (treasuryFee * _preTotalShares) / _preTotalPooledEther;
treasuryFeeShares = (potentialRewards * _socket.treasuryFeeBP * _preTotalShares)
/ (_preTotalPooledEther * BPS_BASE);
}

function _updateVaults(
Expand Down
2 changes: 2 additions & 0 deletions contracts/0.8.25/vaults/interfaces/IHubVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ interface IHubVault {

function inOutDelta() external view returns (int256);

function locked() external view returns (uint256);

function rebalance(uint256 _ether) external payable;

function report(uint256 _valuation, int256 _inOutDelta, uint256 _locked) external;
Expand Down
3 changes: 2 additions & 1 deletion contracts/0.8.9/oracle/AccountingOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,8 @@ contract AccountingOracle is BaseOracle {
data.sharesRequestedToBurn,
data.withdrawalFinalizationBatches,
data.vaultsValues,
data.vaultsNetCashFlows
data.vaultsNetCashFlows,
data.isBunkerMode
)
);

Expand Down
2 changes: 2 additions & 0 deletions contracts/common/interfaces/ReportValues.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ struct ReportValues {
/// @notice netCashFlow of each Lido vault
/// (difference between deposits to and withdrawals from the vault)
int256[] netCashFlows;
/// @notice indicates whether the protocol is in bunker mode
bool isBunkerMode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ contract AccountingOracle__MockForLegacyOracle {
data.sharesRequestedToBurn,
data.withdrawalFinalizationBatches,
new uint256[](0),
new int256[](0)
new int256[](0),
false
)
);
}
Expand Down

0 comments on commit 2cfd7a6

Please sign in to comment.