Skip to content

Commit

Permalink
add: upgrade multiple contracts scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
sirpy committed Dec 9, 2021
1 parent ea41855 commit 8bc860b
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 39 deletions.
68 changes: 68 additions & 0 deletions upgradables/contracts/UpgradeImplSchemeV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: MIT

pragma solidity >=0.6;
pragma experimental ABIEncoderV2;

import "./DAOStackInterfaces.sol";

/* @title Scheme for upgrading an upgradable "uups" contract to new impl
* see openzeppelin upgradables
*/
contract UpgradeImplSchemeV2 {
event UpgradedImpl(address indexed proxy, address impl);

Avatar public avatar;
Controller public controller;
address[] public newImpl;
address[] public proxy;
bytes[] public callData;

/* @dev constructor. Sets the factory address. Reverts if given address is null
* @param _factory The address of the bridge factory
*/
constructor(
Avatar _avatar,
address[] memory _newImpl,
address[] memory _proxy,
bytes[] memory _callData
) public {
newImpl = _newImpl;
avatar = _avatar;
proxy = _proxy;
callData = _callData;
controller = Controller(avatar.owner());
}

/* @dev
* calls upgrade on the proxyadmin contract
*/
function upgrade() public {
for (uint256 i = 0; i < newImpl.length; i++) {
address impl = newImpl[i];
address prx = proxy[i];
if (callData[i].length > 0) {
(bool ok, ) = controller.genericCall(
prx,
abi.encodeWithSignature(
"upgradeToAndCall(address,bytes)",
impl,
callData[i]
),
avatar,
0
);
require(ok, "Calling upgradeAndCall failed");
} else {
(bool ok, ) = controller.genericCall(
prx,
abi.encodeWithSignature("upgradeTo(address)", impl),
avatar,
0
);
require(ok, "Calling upgrade failed");
}
emit UpgradedImpl(prx, impl);
}
selfdestruct(payable(address(avatar)));
}
}
10 changes: 5 additions & 5 deletions upgradables/scripts/getFounders.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//update a contract's web3 to work with accounts read from keystore in production
import { ethers } from "hardhat";
export const getFounders = async network => {
export const getFounders = async (network) => {
const accounts = await ethers.getSigners();
let founders = accounts.slice(0, 3);
if (network.indexOf("production") >= 0) {
const keystore = JSON.parse(process.env.FOUNDERS_KEYSTORE);
founders = keystore.map(key => {
founders = keystore.map((key) => {
return ethers.Wallet.fromEncryptedJsonSync(
JSON.stringify(key),
process.env.FOUNDERS_PASSWORD
Expand All @@ -14,14 +14,14 @@ export const getFounders = async network => {
}

await Promise.all(
founders.map(async f => {
founders.map(async (f) => {
const b = await ethers.provider.getBalance(f.address);
console.log("founder balance:", { f: f.address, b });
if (BigInt(b) < BigInt(ethers.utils.parseEther("0.004"))) {
if (b.lt(ethers.utils.parseEther("0.004"))) {
const toTop = ethers.utils.parseEther("0.009");
const receipt = await founders[0].sendTransaction({
to: f.address,
value: toTop
value: toTop,
});
await receipt.wait();
console.log("topped founder,", { f, receipt });
Expand Down
101 changes: 67 additions & 34 deletions upgradables/scripts/upgradeScheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ networkNames[3] = networkName;
export const proposeUpgradeScheme = async (daoAddresses, schemeAddress) => {
console.log("proposing conntract upgrade to DAO", {
schemeAddress,
daoAddresses
daoAddresses,
});

const schemeRegistrar = (await ethers.getContractAt(
Expand All @@ -26,17 +26,22 @@ export const proposeUpgradeScheme = async (daoAddresses, schemeAddress) => {
schemeAddress,
ethers.constants.HashZero,
"0x00000010",
ethers.constants.HashZero
ethers.constants.HashZero,
{
maxPriorityFeePerGas: 1000000000,
maxFeePerGas: 75000000000,
gasLimit: 2000000,
}
);

const proposal = await proposaltx.wait();
const event = proposal.events.find(_ => _.event === "NewSchemeProposal");
const event = proposal.events.find((_) => _.event === "NewSchemeProposal");
console.log({ proposal: event });
const proposalId = event.args._proposalId;

console.log("proposal", {
scheme: schemeAddress,
proposalId
proposalId,
});
return proposalId;
};
Expand All @@ -50,62 +55,90 @@ export const voteUpgradeScheme = async (network, daoAddresses, proposalId) => {
const founders = await getFounders(network);
console.log("voteUpgradeScheme", { absoluteVote: absoluteVote.address, founders });
await Promise.all(
founders.slice(0, Math.ceil(founders.length / 2)).map(f =>
founders.slice(1).map((f) =>
absoluteVote
.connect(f)
.vote(proposalId, 1, 0, f.address)
.then(_ => _.wait())
.vote(proposalId, 1, 0, f.address, {
maxPriorityFeePerGas: 1000000000,
maxFeePerGas: 75000000000,
gasLimit: 300000,
})
.then((_) => _.wait())
)
);
};

const main = async () => {
const {
daoAddresses,
daoAddresses: fuseAddresses,
mainDaoAddresses: mainnetAddresses,
modelAddresses,
upgradableAddresses,
founders
founders,
} = await getSettings(networkName);

// const implementation = "0x8141208203C298f07dDcd794b14722E69Aa42549";

const deployedProxy = upgradableAddresses.FuseStaking;
const upgradeTimeLock = 0;
const callData = ethers.utils.toUtf8Bytes(""); //ethers.constants.HashZero;
const impl = await (await ethers.getContractFactory("FuseStakingV3")).deploy();
await impl.deployed();
const implementation = impl.address;
console.log("new impl at:", implementation);
const daoAddresses = networkName.includes("mainnet") ? mainnetAddresses : fuseAddresses;

const factory = await ethers.getContractFactory("UpgradeImplScheme");
console.log({ daoAddresses, networkName });
// const implementation = "0x8141208203C298f07dDcd794b14722E69Aa42549";

const scheme = await factory.deploy(
daoAddresses.Avatar,
implementation,
deployedProxy,
upgradableAddresses.ProxyAdmin,
callData,
upgradeTimeLock
// const deployedProxy = upgradableAddresses.FuseStaking;
// const upgradeTimeLock = 0;
// const callData = ethers.utils.toUtf8Bytes(""); //ethers.constants.HashZero;
// const impl = await (await ethers.getContractFactory("FuseStakingV3")).deploy();
// await impl.deployed();
// const implementation = impl.address;
// console.log("new impl at:", implementation);

// const factory = await ethers.getContractFactory("UpgradeImplScheme");
// const scheme = await factory.deploy(
// daoAddresses.Avatar,
// implementation,
// deployedProxy,
// upgradableAddresses.ProxyAdmin,
// callData,
// upgradeTimeLock
// );

const avatar = daoAddresses.Avatar;
const factory = await ethers.getContractFactory("UpgradeImplSchemeV2");
const impls = ["0x9B09A006a9d9455992Ed1bB70D293eBa20071a74"];
const proxies = ["0xd356358f2da1018a3733a304E9bb39CF7ED51059"];
const fixGuardianEncodedFuse =
"0x7d36b66e000000000000000000000000914da3b2508634998d244059dab5488d9ba1814f";
const fixGuardianEncodedEth =
"0x7d36b66e000000000000000000000000f0652a820dd39ec956659e0018da022132f2f40a";
// (
// await ethers.getContractFactory("CompoundVotingMachine")
// ).interface.encodeFunctionData("fixGuardian", [
// "0x914dA3B2508634998d244059dAb5488D9bA1814f", //fuse multisig
// //"0xF0652a820dd39EC956659E0018Da022132f2f40a" //ethereum multisig
// ]);
// const calldatas = [fixGuardianEncodedEth];
// const scheme = await factory.deploy(avatar, impls, proxies, calldatas, {
// maxPriorityFeePerGas: 1000000000,
// maxFeePerGas: 75000000000,
// gasLimit: 2000000,
// });

let scheme = await ethers.getContractAt(
"UpgradeImplSchemeV2",
"0x4A323De87f92c2e24c020551D1E3B24f3AEc744d"
);

// // let scheme = await ethers.getContractAt(
// // "UpgradeImplScheme",
// // "0x2888268C99d9a0dDab53013C6D3c070d118958ec"
// // );

await scheme.deployed();

const schemeAddress = scheme.address;

console.log("upgrade scheme:", schemeAddress);
const proposalId = await proposeUpgradeScheme(daoAddresses, schemeAddress);
// const proposalId = await proposeUpgradeScheme(daoAddresses, schemeAddress);

// const proposalId = "0xda9b0bfa71e0ac696698a16513c18a628cee0a01e85b875c59a8a9c26c23301d";
const proposalId = "0xc1fe81e11fa85a5e7e2cc493951350759fb3c9325f8998e2a5bc8329b8c751a9";
console.log("voting upgrade...", { proposalId });
await voteUpgradeScheme(networkName, daoAddresses, proposalId);
console.log("vote passed, executing upgrade...");
const res = await scheme.upgrade();
console.log({ res });
};

main().catch(e => console.log(e));
main().catch((e) => console.log(e));

0 comments on commit 8bc860b

Please sign in to comment.