Skip to content

Commit

Permalink
added sip script
Browse files Browse the repository at this point in the history
  • Loading branch information
cwsnt committed Dec 18, 2024
1 parent e1bd29c commit 31d29e9
Show file tree
Hide file tree
Showing 2 changed files with 315 additions and 1 deletion.
86 changes: 85 additions & 1 deletion tasks/sips/args/SIPArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,96 @@ const SIPSOV3564 = async (hre): Promise<ISipArgument> => {
return args;
};

const sip0086 = async (
hre: HardhatRuntimeEnvironment
): Promise<ISipArgument> => {
// Replace BasketManagerV3, MassetManager, FeesManager
const {
ethers,
deployments: { get },
network,
} = hre;

const proxyAdmin = await ethers.getContract("MyntAdminProxy");

const targetContractsList = [
"BasketManagerV3",
];

const deploymentProxies = await Promise.all(
targetContractsList.map(async (val) => {
return (await get(val)).address;
})
);

const deploymentImplementations = await Promise.all(
targetContractsList.map(async (val) => {
return (await get(val)).implementation;
})
);

const targetsProxyAdmin = Array(deploymentProxies.length).fill(
proxyAdmin.address
);

// VALIDATE DEPLOYMENTS
const errorLog: string[] = [];
await Promise.all(
deploymentProxies.map(async (proxyAddress, index) => {
if (
(await proxyAdmin.getProxyImplementation(proxyAddress)) ===
deploymentImplementations[index]
) {
errorLog.push(
`Implementation ${targetContractsList[index]} has not changed: ${deploymentImplementations[index]}`
);
}
})
);
if (errorLog.length > 0) {
logger.error(errorLog);
if (
(network.tags.mainnet || network.tags.testnet) &&
!network.tags["forked"]
) {
throw Error("^");
}
}

// CALC SIP ARGS
const datas = deploymentProxies.map((val, index) => {
return ethers.utils.defaultAbiCoder.encode(
["address", "address"],
[deploymentProxies[index], deploymentImplementations[index]]
);
});

const signatures = Array(deploymentProxies.length).fill(
"upgrade(address,address)"
);

const args: ISipArgument = {
args: {
targets: targetsProxyAdmin,
values: Array(deploymentProxies.length).fill(0),
signatures: signatures,
data: datas,
description:
"SIP-0086: Update removeBasset function in BasketManager Mynt, Details: , sha256: ", // @todo update the description
},
governorName: "GovernorOwner",
};

return args;
};

const sipArgs = {
SampleSIP01,
SIPSetMassetManagerProxy,
SIPSetBasketManagerProxy,
sip0072,
SIPSOV3564
SIPSOV3564,
sip0086,
};

export default sipArgs;
230 changes: 230 additions & 0 deletions tests-onchain/sip-0086.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
// first run a local forked mainnet node in a separate terminal window:
// npx hardhat node --fork https://mainnet-dev.sovryn.app/rpc --no-deploy
// now run the test:
// npx hardhat test tests-onchain/sip-0086.test.ts --network rskForkedMainnet
const chai = require("chai");
const { expect } = chai;

import {
mine,
mineUpTo,
time,
setBalance,
reset,
SnapshotRestorer,
takeSnapshot,
} from "@nomicfoundation/hardhat-network-helpers";
import { JsonRpcSigner } from "@ethersproject/providers";
import hre from "hardhat";

const {
ethers,
deployments,
deployments: { createFixture },
} = hre;

const MAX_DURATION = ethers.BigNumber.from(24 * 60 * 60).mul(1092);
const ONE_RBTC = ethers.utils.parseEther("1.0");

describe("SIP-0086 onchain test", () => {
const getImpersonatedSignerFromJsonRpcProvider = async (
addressToImpersonate
) => {
//await impersonateAccount(addressToImpersonate);
//await ethers.provider.send("hardhat_impersonateAccount", [addressToImpersonate]);
//return await ethers.getSigner(addressToImpersonate);
const provider = new ethers.providers.JsonRpcProvider(
"http://localhost:8545"
);
await provider.send("hardhat_impersonateAccount", [addressToImpersonate]);
//return await ethers.getSigner(addressToImpersonate);
return provider.getSigner(addressToImpersonate);
};

const setupTest = createFixture(async ({ deployments, getNamedAccounts }) => {
let { deployer } = await getNamedAccounts();

if (!deployer) {
deployer = (await ethers.getSigners())[0].address;
}

console.log("deployer:", deployer);

const deployerSigner = await ethers.getSigner(deployer);
await setBalance(deployer, ONE_RBTC.mul(10));
/*await deployments.fixture(["StakingModules", "StakingModulesProxy"], {
keepExistingDeployments: true,
}); // start from a fresh deployments
*/
const stakingProxy = await ethers.getContract("StakingProxy", deployer);
const stakingModulesProxy = await ethers.getContract(
"StakingModulesProxy",
deployer
);

const god = await deployments.get("GovernorOwner");
const governorOwner = await ethers.getContract("GovernorOwner");
/*const governorOwner = await ethers.getContractAt(
"GovernorAlpha",
god.address,
deployerSigner
);*/
const governorOwnerSigner: JsonRpcSigner =
(await getImpersonatedSignerFromJsonRpcProvider(
god.address
)) as JsonRpcSigner;

await setBalance(governorOwnerSigner._address, ONE_RBTC);
const timelockOwner = await ethers.getContract(
"TimelockOwner",
governorOwnerSigner
);

const timelockOwnerSigner: JsonRpcSigner =
(await getImpersonatedSignerFromJsonRpcProvider(
timelockOwner.address
)) as JsonRpcSigner;
await setBalance(timelockOwnerSigner._address, ONE_RBTC);

const multisigSigner: JsonRpcSigner =
(await getImpersonatedSignerFromJsonRpcProvider(
(
await deployments.get("MultiSigWallet")
).address
)) as JsonRpcSigner;
//
return {
deployer,
deployerSigner,
stakingProxy,
stakingModulesProxy,
governorOwner,
governorOwnerSigner,
timelockOwner,
timelockOwnerSigner,
multisigSigner,
};
});
let snapshot: SnapshotRestorer;
before(async () => {
await reset("https://mainnet-dev.sovryn.app/rpc", 5911035);
snapshot = await takeSnapshot();
});
async () => {
await snapshot.restore();
};

it("SIP-0086 is executable", async () => {
if (!hre.network.tags["forked"]) return;
const {
deployer,
deployerSigner,
stakingProxy,
governorOwner,
timelockOwnerSigner,
multisigSigner,
} = await setupTest();
// loadFixtureAfterEach = true;
// CREATE PROPOSAL
//console.log("deploying new contracts...");
// await deployments.fixture(
// [
// "BasketManager",
// "MassetManager",
// "FeesManager",
// "FeesVault",
// "MocIntegration",
// ],
// {
// keepExistingDeployments: true,
// }
// );
//console.log("DONE deploying new contracts...");
const sov = await ethers.getContract("SOV", timelockOwnerSigner);
const whaleAmount = (await sov.totalSupply()).mul(ethers.BigNumber.from(5));
await sov.mint(deployerSigner.address, whaleAmount);

/*
const quorumVotes = await governorOwner.quorumVotes();
console.log('quorumVotes:', quorumVotes);
*/
await sov
.connect(deployerSigner)
.approve(stakingProxy.address, whaleAmount);
//const stakeABI = (await hre.artifacts.readArtifact("IStaking")).abi;
const stakeABI = (await deployments.getArtifact("IStaking")).abi;
// const stakeABI = (await ethers.getContractFactory("IStaking")).interface;
// alternatively for stakeABI can be used human readable ABI:
/*const stakeABI = [
'function stake(uint96 amount,uint256 until,address stakeFor,address delegatee)',
'function pauseUnpause(bool _pause)',
'function paused() view returns (bool)'
];*/
const staking = await ethers.getContractAt(
stakeABI,
stakingProxy.address,
deployerSigner
);
/*const multisigSigner = await getImpersonatedSignerFromJsonRpcProvider(
(
await get("MultiSigWallet")
).address
);*/
if (await staking.paused())
await staking.connect(multisigSigner).pauseUnpause(false);
const kickoffTS = await stakingProxy.kickoffTS();
await staking.stake(
whaleAmount,
kickoffTS.add(MAX_DURATION),
deployer,
deployer
);
await mine();

// CREATE PROPOSAL AND VERIFY
const proposalIdBeforeSIP = await governorOwner.proposalCount();
await hre.run("mynt-sips:create", {
argsFunc: "sip0086",
});
const proposalId = await governorOwner.latestProposalIds(deployer);
expect(
proposalId.toNumber(),
"Proposal was not created. Check the SIP creation is not commented out."
).equals(proposalIdBeforeSIP.toNumber() + 1);

// VOTE FOR PROPOSAL
console.log("voting for proposal");
await mine();
await governorOwner.connect(deployerSigner).castVote(proposalId, true);

// QUEUE PROPOSAL
let proposal = await governorOwner.proposals(proposalId);

await mineUpTo(proposal.endBlock);
await mine();

await governorOwner.queue(proposalId);

// EXECUTE PROPOSAL
proposal = await governorOwner.proposals(proposalId);
await time.increaseTo(proposal.eta);
console.log("executing proposal");
await expect(governorOwner.execute(proposalId))
.to.emit(governorOwner, "ProposalExecuted")
.withArgs(proposalId);

// VALIDATE EXECUTION
expect((await governorOwner.proposals(proposalId)).executed).to.be.true;

const {
deployments: { get },
} = hre;
const bmProxyDeployment = await get("BasketManagerV3_Proxy");
const bmDeployment = await get("BasketManagerV3");

const myntAdminProxy = await ethers.getContract("MyntAdminProxy");
expect(
await myntAdminProxy.getProxyImplementation(bmProxyDeployment.address)
).to.equal(bmDeployment.implementation);
});
});

0 comments on commit 31d29e9

Please sign in to comment.