Skip to content
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
10 changes: 5 additions & 5 deletions packages/cli/src/commands/election/activate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,10 @@ testWithAnvilL2(
"SendTransaction: finishNextEpoch",
],
[
"SendTransaction: activate",
"txHash: 0xtxhash",
],
[
"txHash: 0xtxhash",
"SendTransaction: activate",
],
[
"txHash: 0xtxhash",
Expand Down Expand Up @@ -320,9 +320,6 @@ testWithAnvilL2(
[
"SendTransaction: finishNextEpoch",
],
[
"SendTransaction: activate",
],
[
"txHash: 0xtxhash",
],
Expand All @@ -332,6 +329,9 @@ testWithAnvilL2(
[
"txHash: 0xtxhash",
],
[
"SendTransaction: activate",
],
[
"txHash: 0xtxhash",
],
Expand Down
107 changes: 61 additions & 46 deletions packages/cli/src/commands/releasecelo/admin-revoke.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { newReleaseGold } from '@celo/abis/web3/ReleaseGold'
import { releaseGoldABI } from '@celo/abis'
import { StableToken, StrongAddress } from '@celo/base'
import { serializeSignature } from '@celo/base/lib/signatureUtils'
import { ContractKit, newKitFromWeb3 } from '@celo/contractkit'
import { ContractKit, newKitFromProvider } from '@celo/contractkit'
import { AccountsWrapper } from '@celo/contractkit/lib/wrappers/Accounts'
import { GovernanceWrapper } from '@celo/contractkit/lib/wrappers/Governance'
import { ReleaseGoldWrapper } from '@celo/contractkit/lib/wrappers/ReleaseGold'
import { setBalance, testWithAnvilL2, withImpersonatedAccount } from '@celo/dev-utils/anvil-test'
import { getContractFromEvent, timeTravel } from '@celo/dev-utils/ganache-test'
import BigNumber from 'bignumber.js'
import { parseEther } from 'viem'
import { privateKeyToAddress } from 'viem/accounts'
import Web3 from 'web3'
import { topUpWithToken } from '../../test-utils/chain-setup'
import { testLocallyWithWeb3Node } from '../../test-utils/cliUtils'
import { testLocallyWithNode } from '../../test-utils/cliUtils'
import { createMultisig } from '../../test-utils/multisigUtils'
import { deployReleaseGoldContract } from '../../test-utils/release-gold'
import Approve from '../governance/approve'
Expand All @@ -24,54 +24,57 @@ import LockedCelo from './locked-gold'

process.env.NO_SYNCCHECK = 'true'

testWithAnvilL2('releasegold:admin-revoke cmd', (web3: Web3) => {
testWithAnvilL2('releasegold:admin-revoke cmd', (provider) => {
let kit: ContractKit
let contractAddress: StrongAddress
let releaseGoldWrapper: ReleaseGoldWrapper
let accounts: StrongAddress[]

beforeEach(async () => {
accounts = (await web3.eth.getAccounts()) as StrongAddress[]
kit = newKitFromWeb3(web3)
kit = newKitFromProvider(provider)
accounts = (await kit.connection.getAccounts()) as StrongAddress[]
contractAddress = await deployReleaseGoldContract(
web3,
provider,
await createMultisig(kit, [accounts[0], accounts[1]] as StrongAddress[], 2, 2),
accounts[1],
accounts[0],
accounts[2]
)
releaseGoldWrapper = new ReleaseGoldWrapper(
kit.connection,
newReleaseGold(web3, contractAddress),
kit.connection.getCeloContract(releaseGoldABI as any, contractAddress) as any,
kit.contracts
)
})

test('will revoke', async () => {
await testLocallyWithWeb3Node(AdminRevoke, ['--contract', contractAddress, '--yesreally'], web3)
await testLocallyWithNode(AdminRevoke, ['--contract', contractAddress, '--yesreally'], provider)
const revokedContract = await getContractFromEvent(
'ReleaseScheduleRevoked(uint256,uint256)',
web3
provider
)
expect(revokedContract).toBe(contractAddress)
})

test('will rescue all USDm balance', async () => {
await topUpWithToken(kit, StableToken.USDm, accounts[0], new BigNumber('100'))
const stableToken = await kit.contracts.getStableToken()
await stableToken.transfer(contractAddress, 100).send({
const transferHash = await stableToken.transfer(contractAddress, 100, {
from: accounts[0],
})
await testLocallyWithWeb3Node(AdminRevoke, ['--contract', contractAddress, '--yesreally'], web3)
await kit.connection.viemClient.waitForTransactionReceipt({
hash: transferHash as `0x${string}`,
})
await testLocallyWithNode(AdminRevoke, ['--contract', contractAddress, '--yesreally'], provider)
const balance = await stableToken.balanceOf(contractAddress)
expect(balance.isZero()).toBeTruthy()
})

test('will refund and finalize', async () => {
await testLocallyWithWeb3Node(AdminRevoke, ['--contract', contractAddress, '--yesreally'], web3)
await testLocallyWithNode(AdminRevoke, ['--contract', contractAddress, '--yesreally'], provider)
const destroyedContract = await getContractFromEvent(
'ReleaseGoldInstanceDestroyed(address,address)',
web3
provider
)
expect(destroyedContract).toBe(contractAddress)
})
Expand All @@ -81,20 +84,20 @@ testWithAnvilL2('releasegold:admin-revoke cmd', (web3: Web3) => {

beforeEach(async () => {
// Make sure the release gold contract has enough funds
await setBalance(web3, contractAddress, new BigNumber(web3.utils.toWei('10', 'ether')))
await testLocallyWithWeb3Node(CreateAccount, ['--contract', contractAddress], web3)
await testLocallyWithWeb3Node(
await setBalance(provider, contractAddress, new BigNumber(parseEther('10').toString()))
await testLocallyWithNode(CreateAccount, ['--contract', contractAddress], provider)
await testLocallyWithNode(
LockedCelo,
['--contract', contractAddress, '--action', 'lock', '--value', value, '--yes'],
web3
provider
)
})

test('will unlock all gold', async () => {
await testLocallyWithWeb3Node(
await testLocallyWithNode(
AdminRevoke,
['--contract', contractAddress, '--yesreally'],
web3
provider
)
const lockedGold = await kit.contracts.getLockedGold()
const lockedAmount = await lockedGold.getAccountTotalLockedGold(releaseGoldWrapper.address)
Expand All @@ -115,7 +118,7 @@ testWithAnvilL2('releasegold:admin-revoke cmd', (web3: Web3) => {
voteSigner,
PRIVATE_KEY1
)
await testLocallyWithWeb3Node(
await testLocallyWithNode(
Authorize,
[
'--contract',
Expand All @@ -127,15 +130,15 @@ testWithAnvilL2('releasegold:admin-revoke cmd', (web3: Web3) => {
'--signature',
serializeSignature(pop),
],
web3
provider
)
})

it('will rotate vote signer', async () => {
await testLocallyWithWeb3Node(
await testLocallyWithNode(
AdminRevoke,
['--contract', contractAddress, '--yesreally'],
web3
provider
)
const newVoteSigner = await accountsWrapper.getVoteSigner(contractAddress)
expect(newVoteSigner).not.toEqual(voteSigner)
Expand All @@ -148,26 +151,30 @@ testWithAnvilL2('releasegold:admin-revoke cmd', (web3: Web3) => {
// from vote.test.ts
governance = await kit.contracts.getGovernance()
const minDeposit = (await governance.minDeposit()).toFixed()
await governance
.propose([], 'URL')
.sendAndWaitForReceipt({ from: accounts[0], value: minDeposit })
const proposeHash1 = await governance.propose([], 'URL', {
from: accounts[0],
value: minDeposit,
})
await kit.connection.viemClient.waitForTransactionReceipt({
hash: proposeHash1 as `0x${string}`,
})

const dequeueFrequency = (await governance.dequeueFrequency()).toNumber()
await timeTravel(dequeueFrequency + 1, web3)
await timeTravel(dequeueFrequency + 1, provider)
const multiApprover = await governance.getApproverMultisig()
await setBalance(
web3,
provider,
multiApprover.address,
new BigNumber(web3.utils.toWei('10', 'ether'))
new BigNumber(parseEther('10').toString())
)
await withImpersonatedAccount(web3, multiApprover.address, async () => {
await testLocallyWithWeb3Node(
await withImpersonatedAccount(provider, multiApprover.address, async () => {
await testLocallyWithNode(
Approve,
['--from', multiApprover.address, '--proposalID', '1'],
web3
provider
)
})
await testLocallyWithWeb3Node(
await testLocallyWithNode(
GovernanceVote,
[
'--from',
Expand All @@ -179,28 +186,36 @@ testWithAnvilL2('releasegold:admin-revoke cmd', (web3: Web3) => {
'--privateKey',
PRIVATE_KEY1,
],
web3
provider
)
await governance
.propose([], 'URL')
.sendAndWaitForReceipt({ from: accounts[0], value: minDeposit })
await governance
.propose([], 'URL')
.sendAndWaitForReceipt({ from: accounts[0], value: minDeposit })
await testLocallyWithWeb3Node(
const proposeHash2 = await governance.propose([], 'URL', {
from: accounts[0],
value: minDeposit,
})
await kit.connection.viemClient.waitForTransactionReceipt({
hash: proposeHash2 as `0x${string}`,
})
const proposeHash3 = await governance.propose([], 'URL', {
from: accounts[0],
value: minDeposit,
})
await kit.connection.viemClient.waitForTransactionReceipt({
hash: proposeHash3 as `0x${string}`,
})
await testLocallyWithNode(
GovernanceUpvote,
['--from', voteSigner, '--proposalID', '3', '--privateKey', PRIVATE_KEY1],
web3
provider
)
})

it('will revoke governance votes and upvotes', async () => {
const isVotingBefore = await governance.isVoting(contractAddress)
expect(isVotingBefore).toBeTruthy()
await testLocallyWithWeb3Node(
await testLocallyWithNode(
AdminRevoke,
['--contract', contractAddress, '--yesreally'],
web3
provider
)
const isVotingAfter = await governance.isVoting(contractAddress)
expect(isVotingAfter).toBeFalsy()
Expand Down
55 changes: 21 additions & 34 deletions packages/cli/src/commands/releasecelo/admin-revoke.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { StrongAddress } from '@celo/base'
import { Flags } from '@oclif/core'
import prompts from 'prompts'
import { displaySendTx, printValueMap } from '../../utils/cli'
import { displayViemTx, printValueMap } from '../../utils/cli'
import { ReleaseGoldBaseCommand } from '../../utils/release-gold-base'

export default class AdminRevoke extends ReleaseGoldBaseCommand {
Expand All @@ -20,6 +20,7 @@ export default class AdminRevoke extends ReleaseGoldBaseCommand {

async run() {
const kit = await this.getKit()
const publicClient = await this.getPublicClient()
const { flags: _flags } = await this.parse(AdminRevoke)
if (!_flags.yesreally) {
const response = await prompts({
Expand All @@ -38,11 +39,10 @@ export default class AdminRevoke extends ReleaseGoldBaseCommand {

const isRevoked = await this.releaseGoldWrapper.isRevoked()
if (!isRevoked) {
await displaySendTx(
await displayViemTx(
'releasegold: revokeBeneficiary',
this.releaseGoldWrapper.revokeBeneficiary(),
undefined,
'ReleaseScheduleRevoked'
publicClient
)
}

Expand All @@ -55,11 +55,10 @@ export default class AdminRevoke extends ReleaseGoldBaseCommand {
if (voteSigner !== contractAddress) {
voteSigner = kit.defaultAccount
const pop = await accounts.generateProofOfKeyPossession(contractAddress, voteSigner)
await displaySendTx(
await displayViemTx(
'accounts: rotateVoteSigner',
await this.releaseGoldWrapper.authorizeVoteSigner(voteSigner, pop),
undefined,
'VoteSignerAuthorized'
this.releaseGoldWrapper.authorizeVoteSigner(voteSigner, pop),
publicClient
)
}

Expand All @@ -69,13 +68,10 @@ export default class AdminRevoke extends ReleaseGoldBaseCommand {

// handle election votes
if (isElectionVoting) {
const txos = await this.releaseGoldWrapper.revokeAllVotesForAllGroups()
const hashes = await this.releaseGoldWrapper.revokeAllVotesForAllGroups()

for (const txo of txos) {
await displaySendTx('election: revokeVotes', txo, { from: voteSigner }, [
'ValidatorGroupPendingVoteRevoked',
'ValidatorGroupActiveVoteRevoked',
])
for (const hash of hashes) {
await displayViemTx('election: revokeVotes', Promise.resolve(hash), publicClient)
}
}

Expand All @@ -86,53 +82,44 @@ export default class AdminRevoke extends ReleaseGoldBaseCommand {
if (isGovernanceVoting) {
const isUpvoting = await governance.isUpvoting(contractAddress)
if (isUpvoting) {
await displaySendTx(
await displayViemTx(
'governance: revokeUpvote',
await governance.revokeUpvote(contractAddress),
{ from: voteSigner },
'ProposalUpvoteRevoked'
governance.revokeUpvote(contractAddress),
publicClient
)
}

const isVotingReferendum = await governance.isVotingReferendum(contractAddress)
if (isVotingReferendum) {
await displaySendTx(
'governance: revokeVotes',
governance.revokeVotes(),
{ from: voteSigner },
'ProposalVoteRevoked'
)
await displayViemTx('governance: revokeVotes', governance.revokeVotes(), publicClient)
}
}

await displaySendTx(
await displayViemTx(
'releasegold: unlockAllGold',
await this.releaseGoldWrapper.unlockAllGold(),
undefined,
'GoldUnlocked'
this.releaseGoldWrapper.unlockAllGold(),
publicClient
)
}

// rescue any USDm balance
const stabletoken = await kit.contracts.getStableToken()
const cusdBalance = await stabletoken.balanceOf(contractAddress)
if (cusdBalance.isGreaterThan(0)) {
await displaySendTx(
await displayViemTx(
'releasegold: rescueCUSD',
this.releaseGoldWrapper.transfer(kit.defaultAccount, cusdBalance),
undefined,
'Transfer'
publicClient
)
}

// attempt to refund and finalize, surface pending withdrawals
const remainingLockedGold = await this.releaseGoldWrapper.getRemainingLockedBalance()
if (remainingLockedGold.isZero()) {
await displaySendTx(
await displayViemTx(
'releasegold: refundAndFinalize',
this.releaseGoldWrapper.refundAndFinalize(),
undefined,
'ReleaseGoldInstanceDestroyed'
publicClient
)
} else {
console.log('Some celo is still locked, printing pending withdrawals...')
Expand Down
Loading
Loading