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

Feat/upgrade on forking #978

Open
wants to merge 28 commits into
base: feat/vaults
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
42c64b6
feat: untangle Sanity Checker and Locator deployment
arwer13 Mar 7, 2025
3673df4
feat: untangle Delegation deployment and Locator upgrade
arwer13 Mar 8, 2025
ac5e23b
fix: integration tests are now runnable on fork after upgrade
arwer13 Mar 9, 2025
969dcf5
fix: upgrade initialization in Lido and AccountingOracle
arwer13 Mar 10, 2025
9f00310
feat: initial version of upgrade on forking (with template)
arwer13 Mar 10, 2025
9a18b10
fix: ci scratch integration tests (provisioning)
arwer13 Mar 11, 2025
c3840d5
feat: restore CI integration test
arwer13 Mar 11, 2025
2fa8d9a
fix: ci mainnet integration test
arwer13 Mar 11, 2025
ba9417a
feat: move burner burnt shares initialization to upgrade template
arwer13 Mar 11, 2025
ef7c242
fix: burner scratch deployment
arwer13 Mar 11, 2025
43814a5
feat: add Burner migration with stETH in Lido.finalizeUpgrade_v3
arwer13 Mar 14, 2025
67c7d88
fix: add workaround to fix forking forks (e.g. hardhat forking hardhat)
arwer13 Mar 14, 2025
23877f5
fix: ci but setting no chainId on hardhat-node
arwer13 Mar 14, 2025
ed61031
Merge 'feat/vaults' (pdg) into 'feat/ugprade-on-forking'
arwer13 Mar 14, 2025
d1bf561
feat(upgrade): separate mocking aragon voting into yarn command
arwer13 Mar 14, 2025
be49584
fix(tests): update burner migration unit tests
arwer13 Mar 17, 2025
7554864
feat(upgrade): little improvements here and there
arwer13 Mar 17, 2025
a3685a5
fix(upgrade): remove failed unnecessary test and uncomment checks
arwer13 Mar 18, 2025
863a3c0
feat(scratch): save aragon app repo addresses on scratch deploy
arwer13 Mar 18, 2025
df4508d
feat(upgrade): more burner allowance migration + more template checks
arwer13 Mar 19, 2025
8f21f92
feat(upgrade): remove upgrade template from coverage report
arwer13 Mar 19, 2025
896bd55
Merge branch 'feat/vaults' into feat/upgrade-on-forking
arwer13 Mar 20, 2025
1167c03
feat(upgrade): remove WithdrawalVault upgrade from upgrade
arwer13 Mar 20, 2025
47fb019
chore: update .vscode settings.json cSpell.words
arwer13 Mar 20, 2025
57074e0
chore: update .gitignore to include vscode snippets
arwer13 Mar 24, 2025
bf8c893
Merge feat/vaults into feat/upgrade-on-forking
arwer13 Mar 26, 2025
1d0144a
fix: a few integration tests on forking update
arwer13 Mar 26, 2025
d1a589c
Merge branch 'feat/vaults' into feat/upgrade-on-forking
arwer13 Mar 26, 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
7 changes: 2 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -24,12 +24,9 @@ LOCAL_WITHDRAWAL_VAULT_ADDRESS=
LOCAL_STAKING_VAULT_FACTORY_ADDRESS=
LOCAL_STAKING_VAULT_BEACON_ADDRESS=

# RPC URL for a separate, non Hardhat Network node (Anvil, Infura, Alchemy, etc.)
MAINNET_RPC_URL=http://localhost:8545

# RPC URL for Hardhat Network forking, required for running tests on mainnet fork with tracing (Infura, Alchemy, etc.)
# RPC URL for Hardhat Network forking, required for running tests on fork with tracing (Infura, Alchemy, etc.)
# https://hardhat.org/hardhat-network/docs/guides/forking-other-networks#forking-other-networks
FORK_RPC_URL=https://eth.drpc.org
RPC_URL=https://eth.drpc.org

# https://docs.lido.fi/deployed-contracts
MAINNET_LOCATOR_ADDRESS=0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb
44 changes: 31 additions & 13 deletions .github/workflows/tests-integration-mainnet.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
name: Integration Tests
name: Integration Tests On Upgrade
# For local testing of this scenario use ./scripts/dao-upgrade-and-test-on-fork.sh

on: workflow_dispatch

# TODO: uncomment
#on:
# push:
# schedule:
# - cron: "0 10 */2 * *"
on: [push]

jobs:
test_hardhat_integration_fork:
@@ -16,22 +11,45 @@ jobs:

services:
hardhat-node:
image: ghcr.io/lidofinance/hardhat-node:2.22.19
image: ghcr.io/lidofinance/hardhat-node:2.22.19.3
ports:
- 8545:8545
- 8555:8545
env:
ETH_RPC_URL: "${{ secrets.ETH_RPC_URL }}"
DONT_SET_CHAIN_ID: true

steps:
- uses: actions/checkout@v4

- name: Common setup
uses: ./.github/workflows/setup

- name: Set env
run: cp .env.example .env
- name: Prepare network state file
run: cp deployed-mainnet.json deployed-mainnet-upgrade.json

- name: Run upgrade
run: yarn upgrade:deploy
env:
RPC_URL: http://localhost:8555
DEPLOYER: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # first acc of default mnemonic "test test ..."
GAS_PRIORITY_FEE: 1
GAS_MAX_FEE: 100
NETWORK_STATE_FILE: deployed-mainnet-upgrade.json

- name: Mock Aragon voting
run: yarn upgrade:mock-voting
env:
RPC_URL: http://localhost:8555
NETWORK_STATE_FILE: deployed-mainnet-upgrade.json

- name: Finalize scratch deployment
run: yarn hardhat --network local run --no-compile scripts/utils/mine.ts
env:
RPC_URL: http://localhost:8555

- name: Run integration tests
run: yarn test:integration:fork:mainnet
run: yarn test:integration
env:
LOG_LEVEL: debug
RPC_URL: http://localhost:8555
NETWORK_STATE_FILE: deployed-mainnet-upgrade.json
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
.idea/
.yarn/
.vscode/
.vscode/*
!./vscode/settings.json
!./vscode/extensions.json
!./vscode/snippets.code-snippets

node_modules/
coverage/
@@ -26,6 +29,7 @@ accounts.json
deployed-local.json
deployed-hardhat.json
deployed-local-devnet.json
deployed-mainnet-upgrade.json

# MacOS
.DS_Store
1 change: 1 addition & 0 deletions .solcover.js
Original file line number Diff line number Diff line change
@@ -12,5 +12,6 @@ module.exports = {
"common/lib", // 100% covered by test/common/*.t.sol
"0.8.9/lib/UnstructuredStorage.sol", // 100% covered by test/0.8.9/unstructuredStorage.t.sol
"openzeppelin",
"0.8.25/utils/UpgradeTemplateV3.sol",
],
};
23 changes: 22 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -4,5 +4,26 @@
"source.fixAll.eslint": "always"
},
"solidity.defaultCompiler": "remote",
"cSpell.words": ["IETHRegistrarController", "sealables", "streccak", "TmplAppInstalled", "TmplDAOAndTokenDeployed"]
"cSpell.words": [
"automine",
"Codehash",
"disconnecters",
"funders",
"IETHRegistrarController",
"mintable",
"permissionless",
"postdeposits",
"predeposit",
"predeposits",
"rebalancers",
"sdvt",
"sealables",
"streccak",
"TmplAppInstalled",
"TmplDAOAndTokenDeployed",
"Triggerers",
"unvet",
"Unvetting",
"withdrawers"
]
}
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -273,19 +273,19 @@ maintain optimal test performance.

To enable tracing:

- Wrap the code you want to trace with `Tracer.enable()` and `Tracer.disable()` functions.
- Wrap the code you want to trace with `Tracing.enable()` and `Tracing.disable()` functions.
- Run the tests with the appropriate command that enables tracing (e.g., `yarn test:trace`).

Here's an example:

```typescript
import { Tracer } from "test/suite";
import { Tracing } from "test/suite";

describe("MyContract", () => {
it("should do something", async () => {
Tracer.enable();
Tracing.enable();
// code to trace
Tracer.disable();
Tracing.disable();
});
});
```
41 changes: 36 additions & 5 deletions contracts/0.4.24/Lido.sol
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import {AragonApp, UnstructuredStorage} from "@aragon/os/contracts/apps/AragonAp
import {SafeMath} from "@aragon/os/contracts/lib/math/SafeMath.sol";

import {ILidoLocator} from "../common/interfaces/ILidoLocator.sol";
import {IBurner} from "../common/interfaces/IBurner.sol";
import {StakeLimitUtils, StakeLimitUnstructuredStorage, StakeLimitState} from "./lib/StakeLimitUtils.sol";
import {Math256} from "../common/lib/Math256.sol";

@@ -210,10 +211,6 @@ contract Lido is Versioned, StETHPermit, AragonApp {
emit LidoLocatorSet(_lidoLocator);
_initializeEIP712StETH(_eip712StETH);

// set infinite allowance for burner from withdrawal queue
// to burn finalized requests' shares
_approve(ILidoLocator(_lidoLocator).withdrawalQueue(), ILidoLocator(_lidoLocator).burner(), INFINITE_ALLOWANCE);

_initialize_v3();
initialized();
}
@@ -222,19 +219,53 @@ contract Lido is Versioned, StETHPermit, AragonApp {
* @notice A function to finalize upgrade to v3 (from v2). Can be called only once
*
* For more details see https://github.com/lidofinance/lido-improvement-proposals/blob/develop/LIPS/lip-10.md
* @param _oldBurner The address of the old Burner contract to migrate from
*/
function finalizeUpgrade_v3() external {
function finalizeUpgrade_v3(address _oldBurner, address _simpleDvt, address _nodeOperatorsRegistry, address _csmAccounting) external {
require(hasInitialized(), "NOT_INITIALIZED");
_checkContractVersion(2);
require(_oldBurner != address(0), "OLD_BURNER_ADDRESS_ZERO");
require(_oldBurner != getLidoLocator().burner(), "OLD_BURNER_SAME_AS_NEW");

_initialize_v3();

// migrate burner stETH balance
address burner = getLidoLocator().burner();
uint256 oldBurnerShares = _sharesOf(_oldBurner);
if (oldBurnerShares > 0) {
_transferShares(_oldBurner, burner, oldBurnerShares);
_emitTransferEvents(_oldBurner, burner, oldBurnerShares, oldBurnerShares);
}

// initialize new burner with state from the old burner
IBurner(burner).migrate(_oldBurner);

// revoke allowances for the old burner
_approve(getLidoLocator().withdrawalQueue(), _oldBurner, 0);
_approve(_simpleDvt, _oldBurner, 0);
_approve(_nodeOperatorsRegistry, _oldBurner, 0);
_approve(_csmAccounting, _oldBurner, 0);

// set allowances to new burner
_approve(_simpleDvt, burner, INFINITE_ALLOWANCE);
_approve(_nodeOperatorsRegistry, burner, INFINITE_ALLOWANCE);
_approve(_csmAccounting, burner, INFINITE_ALLOWANCE);
// NB: allowances for withdrawalQueue and accounting are set in _initialize_v3()
// because they are required upon scratch deployment as well
}

/**
* initializer for the Lido version "3"
*/
function _initialize_v3() internal {
_setContractVersion(3);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's check oldBurner != newBurner

// Set approvals for the burner
address burner = getLidoLocator().burner();
_approve(getLidoLocator().withdrawalQueue(), burner, INFINITE_ALLOWANCE);
_approve(getLidoLocator().accounting(), burner, INFINITE_ALLOWANCE);
// NB: allowances for simpleDvt and nodeOperatorsRegistry are not set here
// because NodeOperatorsRegistry sets it itself upon scratch deployment
}

/**
2 changes: 1 addition & 1 deletion contracts/0.4.24/template/LidoTemplate.sol
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@ contract LidoTemplate is IsContract {
APMRegistryFactory private apmRegistryFactory;

DeployState private deployState;
APMRepos private apmRepos;
APMRepos public apmRepos;

event TmplAPMDeployed(address apm);
event TmplReposCreated();
Loading

Unchanged files with check annotations Beta

// SPDX-License-Identifier: GPL-3.0
/* See contracts/COMPILERS.md */
pragma solidity 0.4.24;

Check warning on line 5 in contracts/0.4.24/lib/StakeLimitUtils.sol

GitHub Actions / Solhint

Found more than One contract per file. 3 contracts found!
import {UnstructuredStorage} from "@aragon/os/contracts/common/UnstructuredStorage.sol";
/* See contracts/COMPILERS.md */
pragma solidity 0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";

Check warning on line 7 in contracts/0.4.24/oracle/LegacyOracle.sol

GitHub Actions / Solhint

global import of path @aragon/os/contracts/apps/AragonApp.sol is not allowed. Specify names to import individually or bind all exports of the module into a name (import "path" as Name)
import "../../common/interfaces/ILidoLocator.sol";

Check warning on line 9 in contracts/0.4.24/oracle/LegacyOracle.sol

GitHub Actions / Solhint

global import of path ../../common/interfaces/ILidoLocator.sol is not allowed. Specify names to import individually or bind all exports of the module into a name (import "path" as Name)
import "../utils/Versioned.sol";

Check warning on line 11 in contracts/0.4.24/oracle/LegacyOracle.sol

GitHub Actions / Solhint

global import of path ../utils/Versioned.sol is not allowed. Specify names to import individually or bind all exports of the module into a name (import "path" as Name)
interface IAccountingOracle {
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.4.24;
import "@aragon/os/contracts/common/UnstructuredStorage.sol";

Check warning on line 5 in contracts/0.4.24/utils/Versioned.sol

GitHub Actions / Solhint

global import of path @aragon/os/contracts/common/UnstructuredStorage.sol is not allowed. Specify names to import individually or bind all exports of the module into a name (import "path" as Name)
/**
* @title Adapted code of /contracts/0.8.9/utils/Versioned.sol