Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VAULTS] PredepositGuarantee #932

Open
wants to merge 46 commits into
base: feat/vaults
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
c19a543
feat: verify deposit guardian upon deposit
failingtwice Jan 27, 2025
b710b58
feat: add comment
failingtwice Jan 27, 2025
86f80bf
fix: use bytes for sig and XOR for aggregate root
failingtwice Jan 28, 2025
a0de885
fix: remove unused imports
failingtwice Jan 28, 2025
295ba6e
fix: elaborate comment
failingtwice Jan 28, 2025
938a519
feat: predeposit guardian concept WIP, full of bugs and errors
failingtwice Jan 28, 2025
34d203d
refactor: cleanup logic
failingtwice Jan 29, 2025
21f475e
feat: remove unnecessary mapping
failingtwice Jan 29, 2025
331a6e6
feat: remove node operator check
failingtwice Jan 30, 2025
2c84783
fix: rename
failingtwice Jan 30, 2025
ccde1b2
fix: comment on naming
failingtwice Jan 30, 2025
d0954f7
fix: comment on naming
failingtwice Jan 30, 2025
c5312c0
feat: add accounting&delegation to predeposit guardian
Jeday Jan 30, 2025
9d2b349
feat: proof validation
Jeday Jan 31, 2025
e4d3ebc
fix: clean up errors
Jeday Jan 31, 2025
74917ee
fix: mitigate mal staking vault
Jeday Jan 31, 2025
a17c375
fix: prove using validator container
Jeday Feb 3, 2025
8674bba
fix: withdraw
Jeday Feb 3, 2025
87c7e01
fix: use uint256 for collateral
Jeday Feb 3, 2025
ad9e476
fix: merge prove flows
Jeday Feb 3, 2025
5212738
fix: move predeposit to vaults
Jeday Feb 3, 2025
0d5f663
test: pdg cl verifier test
Jeday Feb 4, 2025
ae6d487
fix: use correct merkle implementation
Jeday Feb 4, 2025
2fc25b6
feat: add predeposit guarantee to vault factory
Jeday Feb 5, 2025
563d852
docs: update libs with refs
Jeday Feb 5, 2025
d2f5f24
fix: remove GIndex usage
Jeday Feb 5, 2025
4ef7550
fix: rework no voucher
Jeday Feb 6, 2025
6d6242b
fix: rewrite hashTreeRoot for calldata
Jeday Feb 6, 2025
ecc06c6
test: local testing merkle tree
Jeday Feb 6, 2025
ef47aed
feat: enhance PredepositGuarantee with events and improved error hand…
DiRaiks Feb 6, 2025
3bb45e8
feat: rework for wc proof
Jeday Feb 7, 2025
500e8be
feat: clean up SSZ lib
Jeday Feb 7, 2025
56b7752
docs: clProofVerifier
Jeday Feb 7, 2025
364e1e7
test: update to childBlockTimestamp
Jeday Feb 8, 2025
04a70a9
Merge branch 'predeposit-guardian' of github.com:lidofinance/core int…
DiRaiks Feb 10, 2025
3576bb9
refactor: simplify node operator bond top-up logic
DiRaiks Feb 10, 2025
16014b0
test: export PG test helpers
Jeday Feb 10, 2025
7b61c6a
Merge pull request #936 from lidofinance/predeposit-guardian-fixes
Jeday Feb 10, 2025
6e3b647
feat: integrate predeposit guarantee into locator
Jeday Feb 10, 2025
8c45174
fix: add whenResumed
Jeday Feb 10, 2025
60b3157
fix: move up from internal function
Jeday Feb 11, 2025
3223ab5
test: pdg happy path
Jeday Feb 11, 2025
917c685
fix: enforce balance multiple of ether
Jeday Feb 11, 2025
966ab9c
Merge branch 'feat/vaults' of github.com:lidofinance/core into predep…
Jeday Feb 11, 2025
e79014d
feat: add PDG integration to dashboard
Jeday Feb 12, 2025
d077613
feat: allow GIndex change via slot proof
Jeday Feb 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 19 additions & 25 deletions contracts/0.8.25/Accounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,11 @@ contract Accounting is VaultHub {
/// @notice deposit size in wei (for pre-maxEB accounting)
uint256 private constant DEPOSIT_SIZE = 32 ether;

/// @notice Lido Locator contract
ILidoLocator public immutable LIDO_LOCATOR;
/// @notice Lido contract
ILido public immutable LIDO;

constructor(
ILidoLocator _lidoLocator,
ILido _lido
) VaultHub(_lido) {
LIDO_LOCATOR = _lidoLocator;
LIDO = _lido;
constructor(ILidoLocator _lidoLocator) VaultHub(_lidoLocator) {
LIDO = ILido(_lidoLocator.lido());
}

function initialize(address _admin) external initializer {
Expand Down Expand Up @@ -220,22 +214,27 @@ contract Accounting is VaultHub {
update.withdrawals -
update.principalClBalance + // total cl rewards (or penalty)
update.elRewards + // ELRewards
postExternalEther - _pre.externalEther // vaults rebase
- update.etherToFinalizeWQ; // withdrawals
postExternalEther -
_pre.externalEther - // vaults rebase
update.etherToFinalizeWQ; // withdrawals

// Calculate the amount of ether locked in the vaults to back external balance of stETH
// and the amount of shares to mint as fees to the treasury for each vaults
(update.vaultsLockedEther, update.vaultsTreasuryFeeShares, update.totalVaultsTreasuryFeeShares) =
_calculateVaultsRebase(
update.postTotalShares,
update.postTotalPooledEther,
_pre.totalShares,
_pre.totalPooledEther,
update.sharesToMintAsFees
);
(
update.vaultsLockedEther,
update.vaultsTreasuryFeeShares,
update.totalVaultsTreasuryFeeShares
) = _calculateVaultsRebase(
update.postTotalShares,
update.postTotalPooledEther,
_pre.totalShares,
_pre.totalPooledEther,
update.sharesToMintAsFees
);

update.postTotalPooledEther +=
update.totalVaultsTreasuryFeeShares * update.postTotalPooledEther / update.postTotalShares;
(update.totalVaultsTreasuryFeeShares * update.postTotalPooledEther) /
update.postTotalShares;
update.postTotalShares += update.totalVaultsTreasuryFeeShares;
}

Expand Down Expand Up @@ -308,12 +307,7 @@ contract Accounting is VaultHub {
];
}

LIDO.processClStateUpdate(
_report.timestamp,
_pre.clValidators,
_report.clValidators,
_report.clBalance
);
LIDO.processClStateUpdate(_report.timestamp, _pre.clValidators, _report.clValidators, _report.clBalance);

if (_update.totalSharesToBurn > 0) {
_contracts.burner.commitSharesToBurn(_update.totalSharesToBurn);
Expand Down
122 changes: 122 additions & 0 deletions contracts/0.8.25/lib/GIndex.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// SPDX-FileCopyrightText: 2024 Lido <[email protected]>
// SPDX-License-Identifier: GPL-3.0

/*
GIndex library from CSM
original: https://github.com/lidofinance/community-staking-module/blob/7071c2096983a7780a5f147963aaa5405c0badb1/src/lib/GIndex.sol
*/

pragma solidity 0.8.25;

type GIndex is bytes32;

using {isRoot, isParentOf, index, width, shr, shl, concat, unwrap, pow} for GIndex global;

error IndexOutOfRange();

/// @param gI Is a generalized index of a node in a tree.
/// @param p Is a power of a tree level the node belongs to.
/// @return GIndex
function pack(uint256 gI, uint8 p) pure returns (GIndex) {
if (gI > type(uint248).max) {
revert IndexOutOfRange();
}

// NOTE: We can consider adding additional metadata like a fork version.
return GIndex.wrap(bytes32((gI << 8) | p));
}

function unwrap(GIndex self) pure returns (bytes32) {
return GIndex.unwrap(self);
}

function isRoot(GIndex self) pure returns (bool) {
return index(self) == 1;
}

function index(GIndex self) pure returns (uint256) {
return uint256(unwrap(self)) >> 8;
}

function width(GIndex self) pure returns (uint256) {
return 1 << pow(self);
}

function pow(GIndex self) pure returns (uint8) {
return uint8(uint256(unwrap(self)));
}

/// @return Generalized index of the nth neighbor of the node to the right.
function shr(GIndex self, uint256 n) pure returns (GIndex) {
uint256 i = index(self);
uint256 w = width(self);

if ((i % w) + n >= w) {
revert IndexOutOfRange();
}

return pack(i + n, pow(self));
}

/// @return Generalized index of the nth neighbor of the node to the left.
function shl(GIndex self, uint256 n) pure returns (GIndex) {
uint256 i = index(self);
uint256 w = width(self);

if (i % w < n) {
revert IndexOutOfRange();
}

return pack(i - n, pow(self));
}

// See https://github.com/protolambda/remerkleable/blob/91ed092d08ef0ba5ab076f0a34b0b371623db728/remerkleable/tree.py#L46
function concat(GIndex lhs, GIndex rhs) pure returns (GIndex) {
uint256 lhsMSbIndex = fls(index(lhs));
uint256 rhsMSbIndex = fls(index(rhs));

if (lhsMSbIndex + 1 + rhsMSbIndex > 248) {
revert IndexOutOfRange();
}

return pack((index(lhs) << rhsMSbIndex) | (index(rhs) ^ (1 << rhsMSbIndex)), pow(rhs));
}

function isParentOf(GIndex self, GIndex child) pure returns (bool) {
uint256 parentIndex = index(self);
uint256 childIndex = index(child);

if (parentIndex >= childIndex) {
return false;
}

while (childIndex > 0) {
if (childIndex == parentIndex) {
return true;
}

childIndex = childIndex >> 1;
}

return false;
}

/// @dev From Solady LibBit, see https://github.com/Vectorized/solady/blob/main/src/utils/LibBit.sol.
/// @dev Find last set.
/// Returns the index of the most significant bit of `x`,
/// counting from the least significant bit position.
/// If `x` is zero, returns 256.
function fls(uint256 x) pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
// prettier-ignore
r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x)))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// prettier-ignore
r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0x0706060506020504060203020504030106050205030304010505030400000000))
}
}
Loading
Loading