-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add script to upgrade Pool Voter #47
Changes from 5 commits
396a4dc
0c9f240
c355e75
24bb916
eb8c73b
866d93e
87ca53c
7f2f783
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -165,27 +165,13 @@ abstract contract OmnichainStakingBase is | |
} | ||
|
||
/** | ||
* @dev Unstakes a regular token NFT and transfers it back to the user. | ||
* @param tokenId The ID of the regular token NFT to unstake. | ||
* @notice A single withdraw function to unstake NFT, transfer it back to | ||
* the user, and also withdraw all tokens for `tokenId` from the locker. | ||
* @param tokenId The ID of the regular token NFT to unstake and withdraw. | ||
*/ | ||
function unstakeToken(uint256 tokenId) external updateReward(msg.sender) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we can keep both functions it'll be great. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed here: 87ca53c |
||
require(lockedByToken[tokenId] != address(0), "!tokenId"); | ||
address lockedBy_ = lockedByToken[tokenId]; | ||
if (_msgSender() != lockedBy_) | ||
revert InvalidUnstaker(_msgSender(), lockedBy_); | ||
|
||
delete lockedByToken[tokenId]; | ||
lockedTokenIdNfts[_msgSender()] = deleteAnElement( | ||
lockedTokenIdNfts[_msgSender()], | ||
tokenId | ||
); | ||
|
||
// reset and burn voting power | ||
_burn(msg.sender, tokenPower[tokenId]); | ||
tokenPower[tokenId] = 0; | ||
votingPowerCombined.reset(msg.sender); | ||
|
||
locker.safeTransferFrom(address(this), msg.sender, tokenId); | ||
function unstakeAndWithdraw(uint256 tokenId) external { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we need a nonRentrant hook just for safety There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed here: 87ca53c |
||
_unstakeToken(tokenId); | ||
locker.withdraw(tokenId); | ||
} | ||
|
||
/** | ||
|
@@ -408,6 +394,30 @@ abstract contract OmnichainStakingBase is | |
} | ||
} | ||
|
||
/** | ||
* @dev Unstakes a regular token NFT and transfers it back to the user. | ||
* @param tokenId The ID of the regular token NFT to unstake. | ||
*/ | ||
function _unstakeToken(uint256 tokenId) internal updateReward(msg.sender) { | ||
require(lockedByToken[tokenId] != address(0), "!tokenId"); | ||
address lockedBy_ = lockedByToken[tokenId]; | ||
if (_msgSender() != lockedBy_) | ||
revert InvalidUnstaker(_msgSender(), lockedBy_); | ||
|
||
delete lockedByToken[tokenId]; | ||
lockedTokenIdNfts[_msgSender()] = deleteAnElement( | ||
lockedTokenIdNfts[_msgSender()], | ||
tokenId | ||
); | ||
|
||
// reset and burn voting power | ||
_burn(msg.sender, tokenPower[tokenId]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. checks and balance. move this after the line 415 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @deadshotryker could you please explain this, IMO this shouldn't be after line 415. |
||
tokenPower[tokenId] = 0; | ||
votingPowerCombined.reset(msg.sender); | ||
|
||
locker.safeTransferFrom(address(this), msg.sender, tokenId); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here if we sent the nft to the contract itself, we can withdraw the tokens and send it back to the user in one transaction itself without having to give special approvals. consider adding a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed here: 87ca53c |
||
} | ||
|
||
/** | ||
* @dev Deletes an element from an array. | ||
* @param elements The array to delete from. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import {ethers, upgrades} from "hardhat"; | ||
|
||
const ZERO_TOKEN_ADDRESS = "0x78354f8DcCB269a615A7e0a24f9B0718FDC3C7A7"; | ||
const OMNICHAIN_STAKING_ADDRESS = "0xf374229a18ff691406f99CCBD93e8a3f16B68888"; | ||
|
||
async function main() { | ||
|
||
const poolVoterProxy = "0x5346e9ab27D7874Db95993667D1Cb8338913f0aF" | ||
const poolVoter = await ethers.getContractFactory("PoolVoter"); | ||
|
||
console.log("Upgradig to new PoolVoter implementation"); | ||
|
||
if (ZERO_TOKEN_ADDRESS.length && OMNICHAIN_STAKING_ADDRESS.length) { | ||
|
||
const upgradedPoolVoter = await upgrades.upgradeProxy(poolVoterProxy, poolVoter); | ||
const tx = await upgradedPoolVoter.init(OMNICHAIN_STAKING_ADDRESS, ZERO_TOKEN_ADDRESS); | ||
await tx.wait(); | ||
|
||
console.log("PoolVoter upgraded to", upgradedPoolVoter.address); | ||
} else { | ||
throw new Error("Invalid init arguments"); | ||
} | ||
} | ||
|
||
main().catch((error) => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { expect, should } from "chai"; | ||
import { e18, initMainnetUser } from "../../fixtures/utils"; | ||
import { VestedZeroNFT, VotingPowerCombined } from "../../../typechain-types"; | ||
import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; | ||
import { time } from "@nomicfoundation/hardhat-network-helpers"; | ||
import { setForkBlock } from "../utils"; | ||
import { getNetworkDetails } from "../constants"; | ||
import { | ||
Contract, | ||
ContractTransactionResponse, | ||
parseEther, | ||
parseUnits, | ||
} from "ethers"; | ||
import { ethers } from "hardhat"; | ||
import { getGovernanceContracts } from "../helper"; | ||
|
||
const FORK = process.env.FORK === "true"; | ||
const FORKED_NETWORK = process.env.FORKED_NETWORK ?? ""; | ||
const BLOCK_NUMBER = 5969983; | ||
|
||
const STAKING_ADDRESS = "0xf374229a18ff691406f99CCBD93e8a3f16B68888"; | ||
const REWARD_ADDRESS = "0x78354f8DcCB269a615A7e0a24f9B0718FDC3C7A7"; | ||
const OWNER = "0x0F6e98A756A40dD050dC78959f45559F98d3289d"; | ||
|
||
if (FORK) { | ||
let votingPowerCombined: VotingPowerCombined; | ||
let deployerForked: SignerWithAddress; | ||
describe.only("VotingPowerCombined ForkTests", async () => { | ||
beforeEach(async () => { | ||
votingPowerCombined = await ethers.getContractAt( | ||
"VotingPowerCombined", | ||
"0x2666951A62d82860E8e1385581E2FB7669097647" | ||
); | ||
[deployerForked] = await ethers.getSigners(); | ||
await setForkBlock(BLOCK_NUMBER); | ||
|
||
// | ||
|
||
const poolVoterFactory = await ethers.getContractFactory("PoolVoter"); | ||
const poolVoter = await poolVoterFactory.deploy(); | ||
await poolVoter.init(STAKING_ADDRESS, REWARD_ADDRESS, votingPowerCombined.target); | ||
|
||
const owner = await initMainnetUser(OWNER); | ||
await votingPowerCombined.connect(owner).setAddresses(STAKING_ADDRESS, REWARD_ADDRESS, poolVoter.target); | ||
}); | ||
|
||
it("Should reset voting power", async () => { | ||
const resetterWallet = await initMainnetUser("0x7Ff4e6A2b7B43cEAB1fC07B0CBa00f834846ADEd", parseEther('100')); | ||
|
||
const resetTransaction = votingPowerCombined.connect(resetterWallet).reset(resetterWallet.address); | ||
await expect(resetTransaction).to.not.be.revertedWith('Invalid reset performed'); | ||
}); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't have to modify the lockers now. It'll be a pain to upgrade the lockers as well.
It'll be a lot better to withdraw the tokens within the staking contract itself and send it over to the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved here: 866d93e