Skip to content

Commit

Permalink
feat: add proper upgrade to version 3 in Lido
Browse files Browse the repository at this point in the history
  • Loading branch information
folkyatina committed Nov 27, 2024
1 parent 803199c commit d56c26f
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 144 deletions.
24 changes: 12 additions & 12 deletions contracts/0.4.24/Lido.sol
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ contract Lido is Versioned, StETHPermit, AragonApp {
{
_bootstrapInitialHolder();
_initialize_v2(_lidoLocator, _eip712StETH);
_initialize_v3();
initialized();
}

Expand All @@ -234,23 +235,22 @@ contract Lido is Versioned, StETHPermit, AragonApp {
}

/**
* @notice A function to finalize upgrade to v2 (from v1). Can be called only once
* @dev Value "1" in CONTRACT_VERSION_POSITION is skipped due to change in numbering
*
* The initial protocol token holder must exist.
* initializer for the Lido version "3"
*/
function _initialize_v3() internal {
_setContractVersion(3);
}

/**
* @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
*/
function finalizeUpgrade_v2(address _lidoLocator, address _eip712StETH) external {
_checkContractVersion(0);
function finalizeUpgrade_v3() external {
require(hasInitialized(), "NOT_INITIALIZED");
_checkContractVersion(2);

require(_lidoLocator != address(0), "LIDO_LOCATOR_ZERO_ADDRESS");
require(_eip712StETH != address(0), "EIP712_STETH_ZERO_ADDRESS");

require(_sharesOf(INITIAL_TOKEN_HOLDER) != 0, "INITIAL_HOLDER_EXISTS");

_initialize_v2(_lidoLocator, _eip712StETH);
_initialize_v3();
}

/**
Expand Down
17 changes: 3 additions & 14 deletions test/0.4.24/contracts/Lido__HarnessForFinalizeUpgradeV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,8 @@ pragma solidity 0.4.24;

import {Lido} from "contracts/0.4.24/Lido.sol";

contract Lido__HarnessForFinalizeUpgradeV2 is Lido {
function harness__initialize(uint256 _initialVersion) external payable {
assert(address(this).balance != 0);
_bootstrapInitialHolder();
_setContractVersion(_initialVersion);
initialized();
}

function harness__mintSharesWithoutChecks(address account, uint256 amount) external returns (uint256) {
return super._mintShares(account, amount);
}

function harness__burnInitialHoldersShares() external returns (uint256) {
return super._burnShares(INITIAL_TOKEN_HOLDER, _sharesOf(INITIAL_TOKEN_HOLDER));
contract Lido__HarnessForFinalizeUpgradeV3 is Lido {
function harness_setContractVersion(uint256 _version) external {
_setContractVersion(_version);
}
}
118 changes: 0 additions & 118 deletions test/0.4.24/lido/lido.finalizeUpgrade_v2.test.ts

This file was deleted.

101 changes: 101 additions & 0 deletions test/0.4.24/lido/lido.finalizeUpgrade_v3.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { expect } from "chai";
import { MaxUint256, ZeroAddress } from "ethers";
import { ethers } from "hardhat";

import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers";
import { time } from "@nomicfoundation/hardhat-network-helpers";

import { Lido__HarnessForFinalizeUpgradeV3, LidoLocator } from "typechain-types";

import { certainAddress, INITIAL_STETH_HOLDER, proxify } from "lib";

import { deployLidoLocator } from "test/deploy";
import { Snapshot } from "test/suite";

describe("Lido.sol:finalizeUpgrade_v3", () => {
let deployer: HardhatEthersSigner;

let impl: Lido__HarnessForFinalizeUpgradeV3;
let lido: Lido__HarnessForFinalizeUpgradeV3;
let locator: LidoLocator;

const initialValue = 1n;
const initialVersion = 2n;
const finalizeVersion = 3n;

let withdrawalQueueAddress: string;
let burnerAddress: string;
const eip712helperAddress = certainAddress("lido:initialize:eip712helper");

let originalState: string;

before(async () => {
[deployer] = await ethers.getSigners();
impl = await ethers.deployContract("Lido__HarnessForFinalizeUpgradeV3");
[lido] = await proxify({ impl, admin: deployer });

locator = await deployLidoLocator();
[withdrawalQueueAddress, burnerAddress] = await Promise.all([locator.withdrawalQueue(), locator.burner()]);
});

beforeEach(async () => (originalState = await Snapshot.take()));

afterEach(async () => await Snapshot.restore(originalState));

it("Reverts if not initialized", async () => {
await expect(lido.harness_setContractVersion(initialVersion))
.and.to.emit(lido, "ContractVersionSet")
.withArgs(initialVersion);

await expect(lido.finalizeUpgrade_v3()).to.be.revertedWith("NOT_INITIALIZED");
});

context("initialized", () => {
before(async () => {
const latestBlock = BigInt(await time.latestBlock());

await expect(lido.initialize(locator, eip712helperAddress, { value: initialValue }))
.to.emit(lido, "Submitted")
.withArgs(INITIAL_STETH_HOLDER, initialValue, ZeroAddress)
.and.to.emit(lido, "Transfer")
.withArgs(ZeroAddress, INITIAL_STETH_HOLDER, initialValue)
.and.to.emit(lido, "TransferShares")
.withArgs(ZeroAddress, INITIAL_STETH_HOLDER, initialValue)
.and.to.emit(lido, "ContractVersionSet")
.withArgs(finalizeVersion)
.and.to.emit(lido, "EIP712StETHInitialized")
.withArgs(eip712helperAddress)
.and.to.emit(lido, "Approval")
.withArgs(withdrawalQueueAddress, burnerAddress, MaxUint256)
.and.to.emit(lido, "LidoLocatorSet")
.withArgs(await locator.getAddress());

expect(await impl.getInitializationBlock()).to.equal(MaxUint256);
expect(await lido.getInitializationBlock()).to.equal(latestBlock + 1n);
});

it("Reverts if initialized from scratch", async () => {
await expect(lido.finalizeUpgrade_v3()).to.be.reverted;
});

it("Reverts if contract version does not equal 2", async () => {
const unexpectedVersion = 1n;

await expect(lido.harness_setContractVersion(unexpectedVersion))
.and.to.emit(lido, "ContractVersionSet")
.withArgs(unexpectedVersion);

await expect(lido.finalizeUpgrade_v3()).to.be.reverted;
});

it("Sets contract version to 3", async () => {
await expect(lido.harness_setContractVersion(initialVersion))
.and.to.emit(lido, "ContractVersionSet")
.withArgs(initialVersion);

await expect(lido.finalizeUpgrade_v3()).and.to.emit(lido, "ContractVersionSet").withArgs(finalizeVersion);

expect(await lido.getContractVersion()).to.equal(finalizeVersion);
});
});
});

0 comments on commit d56c26f

Please sign in to comment.