Skip to content

Commit

Permalink
TLC migration to the new schedule (#296)
Browse files Browse the repository at this point in the history
* chore: migration contract & deployment scripts

* Added more tests

* fix: fixed the issue with TLC_migration script

* chore: fixed order of testing

* fix: added check for global unlock ignored flag

* chore: uncommented deploy rate provider

* chore: TLC migration deployment

---------

Co-authored-by: Mischa <[email protected]>
  • Loading branch information
iamsahu and mischat authored Oct 29, 2024
1 parent 53d70ab commit 76d9173
Show file tree
Hide file tree
Showing 9 changed files with 766 additions and 112 deletions.
415 changes: 373 additions & 42 deletions contracts/src/migration/TLC_globalUnlockScheduleMigration.sol

Large diffs are not rendered by default.

192 changes: 134 additions & 58 deletions contracts/test/migration/TLC_globalUnlockScheduleMigration.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,132 @@ import "forge-std/Test.sol";

import "../../src/migration/TLC_globalUnlockScheduleMigration.sol";
import "../../src/TLC.1.sol";
import {ERC20VestableVotesUpgradeableV1} from "contracts/src/components/ERC20VestableVotesUpgradeable.1.sol";

contract TlcMigrationTest is Test {
TlcMigration migrationsContract;
TLCV1 tlc;
string rpc;

uint32[] newLockDuration = [
108604800,
108604800,
108604800,
108604800,
108604800,
108604800,
108604800,
103161600,
98323200,
105235200,
105235200,
105235200,
105235200,
99878400,
89337600,
91065600,
90806400,
86572800,
108604800,
82306800,
108604800,
82306800,
108604800,
82306800,
108604800,
108604800,
108604800,
103161600,
83203200,
83203200,
83548800,
83635200,
83721600,
83548800,
83721600,
83721600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
75693600,
73785600,
81561600,
74476800,
79833600,
77846400,
71020800,
75693600,
75693600,
75693600,
63763200,
64972800,
64713600,
69811200,
69897600,
68688000,
67478400,
65059200,
64454400,
64454400,
59356800,
58924800,
58924800,
57801600,
57110400,
54086400,
57196800,
55641600,
52963200,
55641600,
83116800,
83116800,
54172800,
55641600,
74131200,
49939200,
49334400,
47952000,
47952000,
43286400,
42076800,
46915200,
36979200
];

bool[] isGlobalUnlockedScheduleIgnoredOld;

function setUp() public {
rpc = vm.rpcUrl("mainnet");
vm.createFork(rpc);
}

function testCreate() public {
migrationsContract = new TlcMigration();
}

function testGas() public {
vm.createSelectFork(rpc, 18063740);

vm.createSelectFork(rpc, 20934540);
migrationsContract = new TlcMigration();
proxy tlcProxy = proxy(0xb5Fe6946836D687848B5aBd42dAbF531d5819632);
vm.prank(0x0D1dE267015a75F5069fD1c9ed382210B3002cEb);
Expand All @@ -30,14 +139,17 @@ contract TlcMigrationTest is Test {

function testMigrate() public {
// Significantly faster when cached locally, run a local fork for best perf (anvil recommended)
vm.createSelectFork(rpc, 18063740);
vm.createSelectFork(rpc, 20934540);

proxy tlcProxy = proxy(0xb5Fe6946836D687848B5aBd42dAbF531d5819632);
assertEq(tlcProxy.getVestingScheduleCount(), 67);
assertEq(tlcProxy.getVestingScheduleCount(), 103);

VestingSchedulesV2.VestingSchedule[] memory schedulesBefore = new VestingSchedulesV2.VestingSchedule[](67);
for (uint256 i = 0; i < 67; i++) {
VestingSchedulesV2.VestingSchedule[] memory schedulesBefore = new VestingSchedulesV2.VestingSchedule[](103);
for (uint256 i = 0; i < 103; i++) {
schedulesBefore[i] = TLCV1(address(tlcProxy)).getVestingSchedule(i);
isGlobalUnlockedScheduleIgnoredOld.push(
ERC20VestableVotesUpgradeableV1(address(tlcProxy)).isGlobalUnlockedScheduleIgnored(i)
);
//console.log("%s,%s,%s", i, schedulesBefore[i].start, schedulesBefore[i].end);
}

Expand All @@ -47,69 +159,33 @@ contract TlcMigrationTest is Test {

tlc = new TLCV1();
vm.prank(0x0D1dE267015a75F5069fD1c9ed382210B3002cEb);
tlcProxy.upgradeTo(address(tlc));
tlcProxy.upgradeTo(address(0xF8745c392feF5c91fa1cdB0202efF7Ca08dF55ce));

assertEq(tlcProxy.getVestingScheduleCount(), 67);
assertEq(tlcProxy.getVestingScheduleCount(), 103);

// Check that the all the values that shouldn't change didn't
for (uint256 i = 0; i < 67; i++) {
for (uint256 i = 0; i < tlcProxy.getVestingScheduleCount(); i++) {
VestingSchedulesV2.VestingSchedule memory schedule = TLCV1(address(tlcProxy)).getVestingSchedule(i);
assertEq(schedule.start, schedulesBefore[i].start);
assertEq(schedule.end, schedulesBefore[i].end);
assertEq(schedule.cliffDuration, schedulesBefore[i].cliffDuration);
assertEq(schedule.duration, schedulesBefore[i].duration);
assertEq(schedule.periodDuration, schedulesBefore[i].periodDuration);
assertEq(schedule.amount, schedulesBefore[i].amount);
assertEq(schedule.creator, schedulesBefore[i].creator);
assertEq(schedule.beneficiary, schedulesBefore[i].beneficiary);
assertEq(schedule.revocable, schedulesBefore[i].revocable);
assertEq(schedule.releasedAmount, schedulesBefore[i].releasedAmount);
assertEq(
isGlobalUnlockedScheduleIgnoredOld[i],
ERC20VestableVotesUpgradeableV1(address(tlcProxy)).isGlobalUnlockedScheduleIgnored(i)
);
}
// Check that the value we should have changed did change
// Schedule 0
VestingSchedulesV2.VestingSchedule memory schedule = TLCV1(address(tlcProxy)).getVestingSchedule(0);
assertEq(schedule.start, schedulesBefore[0].start);
assertEq(schedule.end, schedulesBefore[0].end);
assertEq(schedule.lockDuration, 75772800);
assertEq(schedule.cliffDuration, schedulesBefore[0].cliffDuration);
assertEq(schedule.duration, schedulesBefore[0].duration);
assertEq(schedule.periodDuration, schedulesBefore[0].periodDuration);
assertFalse(TLCV1(address(tlcProxy)).isGlobalUnlockedScheduleIgnored(0));

// Schedule 17
schedule = TLCV1(address(tlcProxy)).getVestingSchedule(17);
assertEq(schedule.start, schedulesBefore[17].start);
assertEq(schedule.end, schedulesBefore[17].end);
assertEq(schedule.lockDuration, 53740800);
assertEq(schedule.cliffDuration, schedulesBefore[17].cliffDuration);
assertEq(schedule.duration, schedulesBefore[17].duration);
assertEq(schedule.periodDuration, schedulesBefore[17].periodDuration);
assertTrue(TLCV1(address(tlcProxy)).isGlobalUnlockedScheduleIgnored(17));

// Schedule 36
schedule = TLCV1(address(tlcProxy)).getVestingSchedule(36);
assertEq(schedule.start, 1686175200);
assertEq(schedule.end, 1686261600);
assertEq(schedule.lockDuration, 42861600);
assertEq(schedule.cliffDuration, schedulesBefore[36].cliffDuration);
assertEq(schedule.duration, 86400);
assertEq(schedule.periodDuration, 86400);
assertFalse(TLCV1(address(tlcProxy)).isGlobalUnlockedScheduleIgnored(36));

// Schedule 60
schedule = TLCV1(address(tlcProxy)).getVestingSchedule(60);
assertEq(schedule.start, 1686175200);
assertEq(schedule.end, 1686261600);
assertEq(schedule.lockDuration, 42861600);
assertEq(schedule.cliffDuration, schedulesBefore[60].cliffDuration);
assertEq(schedule.duration, 86400);
assertEq(schedule.periodDuration, 86400);
assertFalse(TLCV1(address(tlcProxy)).isGlobalUnlockedScheduleIgnored(60));

// Schedule 66
schedule = TLCV1(address(tlcProxy)).getVestingSchedule(66);
assertEq(schedule.start, schedulesBefore[66].start);
assertEq(schedule.end, schedulesBefore[66].end);
assertEq(schedule.lockDuration, 38188800);
assertEq(schedule.cliffDuration, schedulesBefore[66].cliffDuration);
assertEq(schedule.duration, schedulesBefore[66].duration);
assertEq(schedule.periodDuration, schedulesBefore[66].periodDuration);
assertTrue(TLCV1(address(tlcProxy)).isGlobalUnlockedScheduleIgnored(66));
for (uint256 i = 0; i < tlcProxy.getVestingScheduleCount(); i++) {
VestingSchedulesV2.VestingSchedule memory schedule = TLCV1(address(tlcProxy)).getVestingSchedule(i);
assertEq(schedule.lockDuration, newLockDuration[i]);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion deploy/mainnet/11_deploy_v1.0.1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
import { isDeployed, logStep, logStepEnd } from "../../ts-utils/helpers/index";

const func: DeployFunction = async function ({ deployments, network, getNamedAccounts }: HardhatRuntimeEnvironment) {
if (!["mainnet", "hardhat"].includes(network.name)) {
if (!["mainnet", "hardhat", "tenderly"].includes(network.name)) {
throw new Error("Invalid network for mainnet deployment");
}

Expand Down
2 changes: 1 addition & 1 deletion deploy/mainnet/12_deploy_v1_1_0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
import { isDeployed, logStep, logStepEnd } from "../../ts-utils/helpers/index";

const func: DeployFunction = async function ({ deployments, network, getNamedAccounts }: HardhatRuntimeEnvironment) {
if (!["mainnet", "hardhat"].includes(network.name)) {
if (!["mainnet", "hardhat", "tenderly"].includes(network.name)) {
throw new Error("Invalid network for mainnet deployment");
}

Expand Down
42 changes: 42 additions & 0 deletions deploy/mainnet/15_TLC_migration_2024.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { DeployFunction } from "hardhat-deploy/dist/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { isDeployed, logStep, logStepEnd } from "../../ts-utils/helpers/index";
import { upgradeTo, upgradeToAndCall, verify } from "../../scripts/helpers";
import { ethers } from "hardhat";

const func: DeployFunction = async function ({ deployments, network, getNamedAccounts }: HardhatRuntimeEnvironment) {
if (!["mainnet", "hardhat", "tenderly"].includes(network.name)) {
throw new Error("Invalid network for mainnet deployment");
}

const { deployer, proxyAdministrator } = await getNamedAccounts();
const tlc = await deployments.get("TLC");
const tlcImplementation = await deployments.get("TLCV1_Implementation_1_1_0");
const tlcProxyFirewall = await deployments.get("TLCProxyFirewall");

const tlcMigrationDeployment = await deployments.deploy("TLC_GlobalUnlockSchedule_Migration_2", {
contract: "TlcMigration",
from: deployer,
log: true,
});

await verify("TlcMigration", tlcMigrationDeployment.address, []);
// migration and upgrade steps
// 1. upgradeToAndCall TlcMigration + TlcMigration.migrate()
// 2. upgradeTo TLCV1_Implementation_1_1_0
logStepEnd(__filename);
};

func.skip = async function ({ deployments, ethers }: HardhatRuntimeEnvironment): Promise<boolean> {
logStep(__filename);
const shouldSkip =
(await isDeployed("TLCV1_Implementation_1_1_0", deployments, __filename)) &&
(await isDeployed("TLC_GlobalUnlockSchedule_Migration_2", deployments, __filename));
if (shouldSkip) {
console.log("Skipped");
logStepEnd(__filename);
}
return shouldSkip;
};

export default func;
108 changes: 108 additions & 0 deletions deployments/mainnet/TLC_GlobalUnlockSchedule_Migration_2.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const config: HardhatUserConfig = {
mainnet: "0x8EE3fC0Bcd7B57429203751C5bE5fdf1AB8409f3",
holesky: "0x80Cf8bD4abf6C078C313f72588720AB86d45c5E6",
devHolesky: "0x0FdEe4562D7e6dbA05A9f892D2Be04B83f3E7579",
tenderly: "0x0FdEe4562D7e6dbA05A9f892D2Be04B83f3E7579",
tenderly: "0x8EE3fC0Bcd7B57429203751C5bE5fdf1AB8409f3",
},
collector: {
default: 1,
Expand Down
65 changes: 56 additions & 9 deletions scripts/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ export const verify = async (name: string, contractAddress: string, args: any, l
if (network.name == "localhost" || network.name == "local") return;
else if (network.name == "tenderly") tenderlyVerify(name, contractAddress);
else {
await hre.run("verify:verify", {
address: contractAddress,
constructorArguments: args,
libraries: {
...libs,
},
}).catch((e) => {
console.log(e.message);
});
await hre
.run("verify:verify", {
address: contractAddress,
constructorArguments: args,
libraries: {
...libs,
},
})
.catch((e) => {
console.log(e.message);
});
}
};

Expand All @@ -26,3 +28,48 @@ const tenderlyVerify = async (name: string, contractAddress: string) => {
});
}
};

export async function upgradeToAndCall(
deployments,
ethers,
newImplementationAddress,
signer,
sendTo,
initData,
upgrading
) {
// Get the ABI for the TransparentUpgradeableProxy
const proxyTransparentArtifact = await deployments.getArtifact("ITransparentUpgradeableProxy");
const proxyTransparentInterface = new ethers.utils.Interface(proxyTransparentArtifact.abi);

const upgradeData = proxyTransparentInterface.encodeFunctionData("upgradeToAndCall", [
newImplementationAddress,
initData,
]);

// Send the transaction
const txCount = await signer.getTransactionCount();
const tx = await signer.sendTransaction({
to: sendTo,
data: upgradeData,
nonce: txCount,
});
await tx.wait();
console.log("tx >> ", tx);
console.log(`${upgrading} proxy upgraded to ${newImplementationAddress} with initialization`);
}

export async function upgradeTo(deployments, ethers, newImplementation, signer, sendTo, upgrading) {
const proxyTransparentArtifact = await deployments.getArtifact("ITransparentUpgradeableProxy");
const proxyTransparentInterface = new ethers.utils.Interface(proxyTransparentArtifact.abi);
let upgradeData = proxyTransparentInterface.encodeFunctionData("upgradeTo", [newImplementation.address]);
let txCount = await signer.getTransactionCount();
let tx = await signer.sendTransaction({
to: sendTo,
data: upgradeData,
nonce: txCount,
});
await tx.wait();
console.log("tx >> ", tx);
console.log(`${upgrading} Proxy upgraded to ${newImplementation.address}`);
}

0 comments on commit 76d9173

Please sign in to comment.