Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

GEN-2786: sunset script #365

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions pkg/deployments/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"defender-relay-client": "^1.37.0",
"fs-extra": "^10.0.1",
"solmate": "transmissions11/solmate#v7",
"web3": "^4.1.2",
"yarn": "^1.22.19"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const { task } = require("hardhat/config");
const contracts = require("../sunset-utils/contracts.json");
const { zeroAddress } = require("../../hardhat.utils");

task("20231031-sunset-remove-rewards-recipients-sanity-check", "Checks Sense has been removed as rewards recipient").setAction(
async (_, { ethers }) => {
const { deployer } = await getNamedAccounts();

// signers
const deployerSigner = await ethers.getSigner(deployer);

// ABIs
const { abi: extractableRewardAbi } = await deployments.getArtifact("ExtractableReward");

// Check if all contracts are sanitised (should be also called after running in multisig)
await sanitiseExtractableContracts(contracts);

////////// HELPERS //////////

async function isExtractableContract(contract) {
try {
await contract.rewardsRecipient();
return true;
} catch (e) {
return false;
}
}

// iterates over the contracts and check that we are not longer a rewards recipient
async function sanitiseExtractableContracts(contracts) {
for (const addresses of Object.values(contracts)) {
for (const contractAddress of addresses) {
const contract = new ethers.Contract(contractAddress, extractableRewardAbi, deployerSigner);
if (
(await isExtractableContract(contract)) &&
(await contract.rewardsRecipient()).toLowerCase() !== zeroAddress()
) {
throw new Error(`Extractable contract ${contractAddress} is not sanitised`);
}
}
}
console.log("All contracts are sanitised");
}
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
const { task } = require("hardhat/config");

const contracts = require("../sunset-utils/contracts.json");
const { CHAINS } = require("../../hardhat.addresses");
const { fund, boostedGasPrice, zeroAddress, stopPrank } = require("../../hardhat.utils");
const { startPrank } = require("../../hardhat.utils");
const { printTxs, getTrustedAddresses, SENSE_ADMIN_ADDRESSES, createBatchFile, getTx } = require("../sunset-utils/helpers");

task("20231031-sunset-remove-rewards-recipients", "Removes Sense as rewards recipient").setAction(async (_, { ethers }) => {
const { deployer } = await getNamedAccounts();
const chainId = await getChainId();
const isFork = chainId == CHAINS.HARDHAT;
console.log(`Deploying from ${deployer} on chain ${chainId}\n`);

if (isFork) await startPrank(SENSE_ADMIN_ADDRESSES.multisig);

// signers
const multisigSigner = await ethers.getSigner(SENSE_ADMIN_ADDRESSES.multisig);
const deployerSigner = await ethers.getSigner(deployer);

// ABIs
const { abi: extractableRewardAbi } = await deployments.getArtifact("ExtractableReward");

let multisigTxs = []; // store all multisig txs to create a JSON

// Fund multisig
if (isFork) await fund(deployerSigner, SENSE_ADMIN_ADDRESSES.multisig, ethers.utils.parseEther("1"));

// (1). For each contract, remove us as reward recipients
for (const address of Object.keys(contracts)) {
for (const contract of contracts[address]) {
console.log(`\n- Processing contract ${contract} -`);
await removeRewardsRecipient(contract);
}
}

// Log functions to execute from multisig
printTxs(multisigTxs);
multisigTxs.forEach(tx => {
delete tx.method;
});

// (2). Prepare JSON file with batched txs for Gnosis Safe Transaction Builder UI
createBatchFile("sense-v1-sunset-batch-1", new Date().toISOString().slice(0, 10), multisigTxs);

////////// HELPERS //////////

// set reward recipient to zero address
async function removeRewardsRecipient(address) {
let contract = new ethers.Contract(address, extractableRewardAbi, multisigSigner);

// Check if contract is ExtractableReward.sol
if (!(await isExtractableContract(contract))) {
console.log(` * Is not an extractable contract`);
return;
}

const trusted = await getTrustedAddresses(contract);
const rewardsRecipient = (await contract.rewardsRecipient()).toLowerCase();
const isDeployerTrusted = trusted.sense.includes(SENSE_ADMIN_ADDRESSES.deployer);
const isMultisigTrusted = trusted.sense.includes(SENSE_ADMIN_ADDRESSES.multisig);

if (Object.values(SENSE_ADMIN_ADDRESSES).includes(rewardsRecipient)) {
contract = isDeployerTrusted ? contract.connect(deployerSigner) : contract;

if (isFork && isDeployerTrusted) await stopPrank(SENSE_ADMIN_ADDRESSES.multisig);

if (isFork || isDeployerTrusted) {
await contract
.setRewardsRecipient(zeroAddress(), { gasPrice: boostedGasPrice() })
.then(t => t.wait());

if (isFork) await startPrank(SENSE_ADMIN_ADDRESSES.multisig); // assuming this is how you restart the prank
}

if (!isDeployerTrusted && isMultisigTrusted) {
multisigTxs.push(
getTx(
address,
"setRewardsRecipient",
contract.interface.encodeFunctionData("setRewardsRecipient", [zeroAddress()]),
),
);
}

console.log(` * Rewards recipient set to zero address`);
} else {
console.log(` * Rewards recipient is already zero address`);
}
}

async function isExtractableContract(contract) {
try {
await contract.rewardsRecipient();
return true;
} catch (e) {
return false;
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const { task } = require("hardhat/config");

const contracts = require("../sunset-utils/contracts.json");
const { SENSE_ADMIN_ADDRESSES } = require("../sunset-utils/helpers");

task("20231031-sunset-remove-trust-sanity-check", "Checks trust has been removed").setAction(async (_, { ethers }) => {
const { deployer } = await getNamedAccounts();
const deployerSigner = await ethers.getSigner(deployer);
const { abi: trustAbi } = await deployments.getArtifact("Trust");

// Check if all contracts are sanitised (should be also called after running in multisig)
await sanitiseTrustContracts(contracts);

async function isTrustContract(contract) {
try {
await contract.isTrusted(SENSE_ADMIN_ADDRESSES.multisig);
return true;
} catch (e) {
return false;
}
}

// iterates over the contracts and check that we are not longer trusted
async function sanitiseTrustContracts(allContracts) {
for (const addresses of Object.values(allContracts)) {
for (const contractAddress of addresses) {
const contract = new ethers.Contract(contractAddress, trustAbi, deployerSigner);
for (const address of Object.values(SENSE_ADMIN_ADDRESSES)) {
if ((await isTrustContract(contract)) && (await contract.isTrusted(address))) {
throw new Error(`Trust contract ${contractAddress} is not sanitised. It's still trusting ${address}`);
}
}
}
}
console.log("All contracts are sanitised");
}
});
118 changes: 118 additions & 0 deletions pkg/deployments/tasks/20231031-sunset-remove-trust/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
const { task } = require("hardhat/config");
const data = require("./input");

const contracts = require("../sunset-utils/contracts.json");
const { CHAINS } = require("../../hardhat.addresses");
const { fund, boostedGasPrice, stopPrank } = require("../../hardhat.utils");
const { startPrank } = require("../../hardhat.utils");
const { SENSE_ADMIN_ADDRESSES, printTxs, createBatchFile, getTx, getTrustedAddresses } = require("../sunset-utils/helpers");

task("20231031-sunset-remove-trust", "Removes Sense as trusted address").setAction(async (_, { ethers }) => {
const { deployer } = await getNamedAccounts();
const chainId = await getChainId();
const isFork = chainId == CHAINS.HARDHAT;
console.log(`Deploying from ${deployer} on chain ${chainId}\n`);

if (isFork) await startPrank(SENSE_ADMIN_ADDRESSES.multisig);

// signers
const multisigSigner = await ethers.getSigner(SENSE_ADMIN_ADDRESSES.multisig);
const deployerSigner = await ethers.getSigner(deployer);

// ABIs
const { abi: dividerAbi } = await deployments.getArtifact("Divider");
const { abi: trustAbi } = await deployments.getArtifact("Trust");

// divider
const { divider: dividerAddress } = data[chainId] || data[CHAINS.MAINNET];
let divider = new ethers.Contract(dividerAddress, dividerAbi, multisigSigner);

const SET_IS_TRUSTED_DATA = divider.interface.encodeFunctionData("setIsTrusted", [
SENSE_ADMIN_ADDRESSES.multisig,
false,
]);

let multisigTxs = []; // store all multisig txs to create a JSON

// Fund multisig
if (isFork) await fund(deployerSigner, SENSE_ADMIN_ADDRESSES.multisig, ethers.utils.parseEther("1"));

// (1). Turn permissionless mode ON
if (!(await divider.permissionless())) {
if (isFork) await divider.setPermissionless(true, { gasPrice: boostedGasPrice() }).then(t => t.wait());
multisigTxs.push(
getTx(
dividerAddress,
"setPermissionless",
divider.interface.encodeFunctionData("setPermissionless", [true]),
),
);
console.log(`- Permissionless mode turned ON`);
} else {
console.log(`- Skipped as permissionless mode is already ON`);
}

// (2). For each contract, remove us as trusted addresses
for (const address of Object.keys(contracts)) {
for (const contract of contracts[address]) {
console.log(`\n- Processing contract ${contract} -`);
await removeTrust(contract);
}
}

// Log functions to execute from multisig
printTxs(multisigTxs);
multisigTxs.forEach(tx => {
delete tx.method;
});

// (3). Prepare JSON file with batched txs for Gnosis Safe Transaction Builder UI
createBatchFile("sense-v1-sunset-batch-2", new Date().toISOString().slice(0, 10), multisigTxs);

////////// HELPERS //////////

// make sure there are no more sense addresses trusted
async function removeTrust(address) {
let contract = new ethers.Contract(address, trustAbi, multisigSigner);

// Validate if the contract has the 'isTrusted' method
if (!(await isTrustContract(contract))) {
console.log(` * Is not a trust contract`);
return;
}

const trusted = await getTrustedAddresses(contract);
if (trusted.sense.length === 0) {
console.log(` * No trusted addresses`);
return;
}

const isDeployerTrusted = trusted.sense.includes(SENSE_ADMIN_ADDRESSES.deployer);
const isMultisigTrusted = trusted.sense.includes(SENSE_ADMIN_ADDRESSES.multisig);
contract = isDeployerTrusted ? contract.connect(deployerSigner) : contract;
if (isFork && isDeployerTrusted) await stopPrank(SENSE_ADMIN_ADDRESSES.multisig);

for (const trustAddress of trusted.sense) {
if (isFork || isDeployerTrusted) {
await contract.setIsTrusted(trustAddress, false, { gasPrice: boostedGasPrice() }).then(t => t.wait());
}

if (!isDeployerTrusted && isMultisigTrusted) {
multisigTxs.push(getTx(contract.address, "setIsTrusted", SET_IS_TRUSTED_DATA));
}
}

console.log(` * ${address} is no longer trusted`);
if (trusted.other.length > 0) console.log(` * Other trusted addresses: ${trusted.other}`);
if (isFork && isDeployerTrusted) await startPrank(SENSE_ADMIN_ADDRESSES.multisig);
}

async function isTrustContract(contract) {
try {
await contract.isTrusted(SENSE_ADMIN_ADDRESSES.multisig);
return true;
} catch (e) {
return false;
}
}
});
6 changes: 6 additions & 0 deletions pkg/deployments/tasks/20231031-sunset-remove-trust/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
// mainnet
1: {
divider: "0x86bA3E96Be68563E41c2f5769F1AF9fAf758e6E0",
},
};
5 changes: 5 additions & 0 deletions pkg/deployments/tasks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ require("./20221512-factories-and-idle");
require("./20230102-ownable-erc4626-crop-factory");
require("./20230726-periphery-v2");
require("./20230321-aura");
require("./20231031-sunset");
require("./20231031-sunset-remove-rewards-recipients");
require("./20231031-sunset-remove-rewards-recipients-sanity-check");
require("./20231031-sunset-remove-trust");
require("./20231031-sunset-remove-trust-sanity-check");

// utils
require("./goerli-tokens-factories");
Expand Down
Loading