test(governance): new and update market proposal forms (#3131)

This commit is contained in:
Joe Tsang 2023-03-10 14:03:36 +00:00 committed by GitHub
parent 327ebf3496
commit b3bfb90804
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 364 additions and 69 deletions

View File

@ -22,7 +22,7 @@
"filters": [ "filters": [
{ {
"key": { "key": {
"name": "prices.ETH.value", "name": "prices.BTC.value",
"type": "TYPE_INTEGER", "type": "TYPE_INTEGER",
"numberDecimalPlaces": "0" "numberDecimalPlaces": "0"
}, },
@ -38,30 +38,34 @@
} }
}, },
"dataSourceSpecForTradingTermination": { "dataSourceSpecForTradingTermination": {
"signers": [ "external": {
{ "oracle": {
"pubKey": { "signers": [
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "trading.terminated.ETH5",
"type": "TYPE_BOOLEAN"
},
"conditions": [
{ {
"operator": "OPERATOR_EQUALS", "pubKey": {
"value": "true" "key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "trading.terminated.ETH5",
"type": "TYPE_BOOLEAN"
},
"conditions": [
{
"operator": "OPERATOR_EQUALS",
"value": "true"
}
]
} }
] ]
} }
] }
}, },
"dataSourceSpecBinding": { "dataSourceSpecBinding": {
"settlementPriceProperty": "prices.BTC.value", "settlementDataProperty": "prices.BTC.value",
"tradingTerminationProperty": "trading.terminated.ETH5" "tradingTerminationProperty": "trading.terminated.ETH5"
} }
} }

View File

@ -0,0 +1,86 @@
{
"lpPriceRange": "11",
"instrument": {
"code": "Token.24h",
"future": {
"quoteName": "fBTC",
"dataSourceSpecForSettlementData": {
"external": {
"oracle": {
"signers": [
{
"pubKey": {
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "prices.BTC.value",
"type": "TYPE_INTEGER"
},
"conditions": [
{
"operator": "OPERATOR_GREATER_THAN",
"value": "0"
}
]
}
]
}
}
},
"dataSourceSpecForTradingTermination": {
"external": {
"oracle": {
"signers": [
{
"pubKey": {
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "trading.terminated.ETH5",
"type": "TYPE_BOOLEAN"
},
"conditions": [
{
"operator": "OPERATOR_GREATER_THAN_OR_EQUAL",
"value": "1648684800000000000"
}
]
}
]
}
}
},
"dataSourceSpecBinding": {
"settlementDataProperty": "prices.BTC.value",
"tradingTerminationProperty": "trading.terminated.ETH5"
}
}
},
"metadata": ["sector:energy", "sector:food", "source:docs.vega.xyz"],
"priceMonitoringParameters": {
"triggers": [
{
"horizon": "43200",
"probability": "0.9999999",
"auctionExtension": "600"
}
]
},
"logNormal": {
"tau": 0.0001140771161,
"riskAversionParameter": 0.001,
"params": {
"mu": 0,
"r": 0.016,
"sigma": 0.3
}
}
}

View File

@ -1,62 +1,76 @@
{ {
"lpPriceRange": "10",
"instrument": { "instrument": {
"code": "TEST.24h", "code": "TEST.24h",
"future": { "future": {
"quoteName": "fUSDC", "quoteName": "fUSDC",
"settlementDataDecimals": 5,
"dataSourceSpecForSettlementData": { "dataSourceSpecForSettlementData": {
"signers": [ "external": {
{ "oracle": {
"pubKey": { "signers": [
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "prices.ETH.value",
"type": "TYPE_INTEGER"
},
"conditions": [
{ {
"operator": "OPERATOR_GREATER_THAN", "pubKey": {
"value": "0" "key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "prices.ETH.value",
"type": "TYPE_INTEGER",
"numberDecimalPlaces": "0"
},
"conditions": [
{
"operator": "OPERATOR_GREATER_THAN",
"value": "0"
}
]
} }
] ]
} }
] }
}, },
"dataSourceSpecForTradingTermination": { "dataSourceSpecForTradingTermination": {
"signers": [ "external": {
{ "oracle": {
"pubKey": { "signers": [
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "trading.terminated.ETH5",
"type": "TYPE_BOOLEAN"
},
"conditions": [
{ {
"operator": "OPERATOR_GREATER_THAN_OR_EQUAL", "pubKey": {
"value": "1648684800000000000" "key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
}
}
],
"filters": [
{
"key": {
"name": "trading.terminated.ETH5",
"type": "TYPE_BOOLEAN"
},
"conditions": [
{
"operator": "OPERATOR_EQUALS",
"value": "true"
}
]
} }
] ]
} }
] }
}, },
"dataSourceSpecBinding": { "dataSourceSpecBinding": {
"settlementPriceProperty": "prices.ETH.value", "settlementDataProperty": "prices.ETH.value",
"tradingTerminationProperty": "trading.terminated.ETH5" "tradingTerminationProperty": "trading.terminated.ETH5"
} }
} }
}, },
"metadata": ["sector:energy", "sector:food", "source:docs.vega.xyz"], "metadata": [
"sector:energy",
"sector:food",
"source:docs.vega.xyz",
"test:update"
],
"priceMonitoringParameters": { "priceMonitoringParameters": {
"triggers": [ "triggers": [
{ {
@ -66,6 +80,14 @@
} }
] ]
}, },
"liquidityMonitoringParameters": {
"targetStakeParameters": {
"timeWindow": "3600",
"scalingFactor": 10
},
"triggeringRatio": "0.7",
"auctionExtension": "1"
},
"logNormal": { "logNormal": {
"tau": 0.0001140771161, "tau": 0.0001140771161,
"riskAversionParameter": 0.001, "riskAversionParameter": 0.001,

View File

@ -26,6 +26,10 @@ const enactmentDeadlineError =
'[data-testid="enactment-before-voting-deadline"]'; '[data-testid="enactment-before-voting-deadline"]';
const proposalDownloadBtn = '[data-testid="proposal-download-json"]'; const proposalDownloadBtn = '[data-testid="proposal-download-json"]';
const feedbackError = '[data-testid="Error"]'; const feedbackError = '[data-testid="Error"]';
const viewProposalBtn = 'view-proposal-btn';
const liquidityVoteStatus = 'liquidity-votes-status';
const tokenVoteStatus = 'token-votes-status';
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
const epochTimeout = Cypress.env('epochTimeout'); const epochTimeout = Cypress.env('epochTimeout');
const proposalTimeout = { timeout: 14000 }; const proposalTimeout = { timeout: 14000 };
@ -45,6 +49,7 @@ context(
{ tags: '@slow' }, { tags: '@slow' },
function () { function () {
before('connect wallets and set approval limit', function () { before('connect wallets and set approval limit', function () {
cy.createMarket();
cy.visit('/'); cy.visit('/');
cy.vega_wallet_set_specified_approval_amount('1000'); cy.vega_wallet_set_specified_approval_amount('1000');
}); });
@ -65,7 +70,7 @@ context(
// 3002-PROP-007 // 3002-PROP-007
cy.get(newProposalDescription).type('E2E test for proposals'); cy.get(newProposalDescription).type('E2E test for proposals');
cy.get(proposalParameterSelect).find('option').should('have.length', 116); cy.get(proposalParameterSelect).find('option').should('have.length', 117);
cy.get(proposalParameterSelect).select( cy.get(proposalParameterSelect).select(
// 3007-PNEC-002 // 3007-PNEC-002
'governance_proposal_asset_minEnact' 'governance_proposal_asset_minEnact'
@ -175,9 +180,8 @@ context(
cy.get(enactmentDeadlineError).should('not.exist'); cy.get(enactmentDeadlineError).should('not.exist');
}); });
// Skipping because unclear what the required json is yet for new market proposal, will update once docs have been updated // 3003-PMAN-001
// 3003-todo-PMAN-001 it('Able to submit valid new market proposal', function () {
it.skip('Able to submit valid new market proposal', function () {
cy.go_to_make_new_proposal(governanceProposalType.NEW_MARKET); cy.go_to_make_new_proposal(governanceProposalType.NEW_MARKET);
cy.get(newProposalTitle).type('Test new market proposal'); cy.get(newProposalTitle).type('Test new market proposal');
cy.get(newProposalDescription).type('E2E test for proposals'); cy.get(newProposalDescription).type('E2E test for proposals');
@ -199,6 +203,7 @@ context(
cy.get(newProposalTitle).type('Test new market proposal'); cy.get(newProposalTitle).type('Test new market proposal');
cy.get(newProposalDescription).type('E2E test for proposals'); cy.get(newProposalDescription).type('E2E test for proposals');
cy.fixture('/proposals/new-market').then((newMarketProposal) => { cy.fixture('/proposals/new-market').then((newMarketProposal) => {
newMarketProposal.invalid = 'I am an invalid field';
let newMarketPayload = JSON.stringify(newMarketProposal); let newMarketPayload = JSON.stringify(newMarketProposal);
cy.get(newProposalTerms).type(newMarketPayload, { cy.get(newProposalTerms).type(newMarketPayload, {
parseSpecialCharSequences: false, parseSpecialCharSequences: false,
@ -209,11 +214,66 @@ context(
cy.contains('Transaction failed', proposalTimeout).should('be.visible'); cy.contains('Transaction failed', proposalTimeout).should('be.visible');
cy.get(feedbackError).should( cy.get(feedbackError).should(
'have.text', 'have.text',
'Invalid params: the transaction is malformed' 'Invalid params: the transaction is not a valid Vega command: unknown field "invalid" in vega.NewMarket'
); );
}); });
it.skip('Able to submit update market proposal', function () { // Will fail if run after 'Able to submit update market proposal and vote for proposal'
// 3002-PROP-022
it('Unable to submit update market proposal without equity-like share in the market', function () {
cy.go_to_make_new_proposal(governanceProposalType.UPDATE_MARKET);
cy.get(newProposalTitle).type('Test update market proposal - rejected');
cy.get(newProposalDescription).type('E2E test for proposals');
cy.get(proposalMarketSelect).select('Test market 1');
cy.fixture('/proposals/update-market').then((updateMarketProposal) => {
let newUpdateMarketProposal = JSON.stringify(updateMarketProposal);
cy.get(newProposalTerms).type(newUpdateMarketProposal, {
parseSpecialCharSequences: false,
delay: 2,
});
});
cy.get(newProposalSubmitButton).should('be.visible').click();
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
cy.getByTestId('dialog-content')
.find('p')
.should('have.text', 'PROPOSAL_ERROR_INSUFFICIENT_EQUITY_LIKE_SHARE');
cy.ensure_specified_unstaked_tokens_are_associated('1');
});
// 3002-PROP-020
it('Unable to submit update market proposal without minimum amount of tokens', function () {
cy.vega_wallet_teardown();
cy.vega_wallet_faucet_assets_without_check(
'fUSDC',
'1000000',
vegaWalletPublicKey
);
cy.go_to_make_new_proposal(governanceProposalType.UPDATE_MARKET);
cy.get(newProposalTitle).type('Test update market proposal - rejected');
cy.get(newProposalDescription).type('E2E test for proposals');
cy.get(proposalMarketSelect).select('Test market 1');
cy.fixture('/proposals/update-market').then((updateMarketProposal) => {
let newUpdateMarketProposal = JSON.stringify(updateMarketProposal);
cy.get(newProposalTerms).type(newUpdateMarketProposal, {
parseSpecialCharSequences: false,
delay: 2,
});
});
cy.get(newProposalSubmitButton).should('be.visible').click();
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
cy.get(feedbackError).should(
'have.text',
'Network error: the network blocked the transaction through the spam protection: party has insufficient associated governance tokens in their staking account to submit proposal request (ABCI code 89)'
);
});
// 3001-VOTE-092
it('Able to submit update market proposal and vote for proposal', function () {
cy.vega_wallet_faucet_assets_without_check(
'fUSDC',
'1000000',
vegaWalletPublicKey
);
cy.go_to_make_new_proposal(governanceProposalType.UPDATE_MARKET); cy.go_to_make_new_proposal(governanceProposalType.UPDATE_MARKET);
cy.get(newProposalTitle).type('Test update market proposal'); cy.get(newProposalTitle).type('Test update market proposal');
cy.get(newProposalDescription).type('E2E test for proposals'); cy.get(newProposalDescription).type('E2E test for proposals');
@ -222,6 +282,10 @@ context(
cy.get('dd').eq(0).should('have.text', 'Test market 1'); cy.get('dd').eq(0).should('have.text', 'Test market 1');
cy.get('dd').eq(1).should('have.text', 'TEST.24h'); cy.get('dd').eq(1).should('have.text', 'TEST.24h');
cy.get('dd').eq(2).should('not.be.empty'); cy.get('dd').eq(2).should('not.be.empty');
cy.get('dd').eq(2).invoke('text').as('EnactedMarketId');
});
cy.get('@EnactedMarketId').then((marketId) => {
cy.VegaWalletSubmitLiquidityProvision(marketId, '1');
}); });
cy.fixture('/proposals/update-market').then((updateMarketProposal) => { cy.fixture('/proposals/update-market').then((updateMarketProposal) => {
let newUpdateMarketProposal = JSON.stringify(updateMarketProposal); let newUpdateMarketProposal = JSON.stringify(updateMarketProposal);
@ -232,6 +296,34 @@ context(
}); });
cy.get(newProposalSubmitButton).should('be.visible').click(); cy.get(newProposalSubmitButton).should('be.visible').click();
cy.wait_for_proposal_submitted(); cy.wait_for_proposal_submitted();
cy.navigate_to('proposals');
cy.get('@EnactedMarketId').then((marketId) => {
cy.contains(marketId)
.parentsUntil(proposalListItem)
.within(() => {
cy.getByTestId(viewProposalBtn).click();
});
});
cy.getByTestId(liquidityVoteStatus).should(
'contain.text',
'Currently expected to fail'
);
cy.getByTestId(tokenVoteStatus).should(
'contain.text',
'Currently expected to fail'
);
cy.vote_for_proposal('for');
cy.getByTestId(liquidityVoteStatus).should(
'contain.text',
'Currently expected to pass'
);
cy.getByTestId(tokenVoteStatus).should(
'contain.text',
'Currently expected to pass'
);
cy.get_proposal_information_from_table('Expected to pass')
.contains('👍 by Token vote')
.should('be.visible');
}); });
// 3001-VOTE-026 3001-VOTE-027 3001-VOTE-028 3001-VOTE-095 3001-VOTE-096 3005-PASN-001 // 3001-VOTE-026 3001-VOTE-027 3001-VOTE-028 3001-VOTE-095 3001-VOTE-096 3005-PASN-001
@ -298,7 +390,7 @@ context(
.parentsUntil(proposalListItem) .parentsUntil(proposalListItem)
.within(() => { .within(() => {
cy.get(proposalDetails).should('contain.text', assetId); // 3001-VOTE-029 cy.get(proposalDetails).should('contain.text', assetId); // 3001-VOTE-029
cy.getByTestId('view-proposal-btn').click(); cy.getByTestId(viewProposalBtn).click();
}); });
}); });
cy.get_proposal_information_from_table('Proposed enactment') // 3001-VOTE-044 cy.get_proposal_information_from_table('Proposed enactment') // 3001-VOTE-044

View File

@ -82,9 +82,10 @@ Cypress.Commands.add(
Cypress.Commands.add( Cypress.Commands.add(
'get_submitted_proposal_from_proposal_list', 'get_submitted_proposal_from_proposal_list',
(proposalTitle) => { (proposalTitle) => {
cy.get_proposal_id_from_list(proposalTitle); cy.get_proposal_id_from_list(proposalTitle).then(() => {
cy.get('@proposalIdText').then((proposalId) => { cy.get('@proposalIdText').then((proposalId) => {
return cy.get(`#${proposalId}`); return cy.get(`#${proposalId}`);
});
}); });
} }
); );

View File

@ -56,7 +56,7 @@ export const VoteDetails = ({
{proposalType === ProposalType.PROPOSAL_UPDATE_MARKET && ( {proposalType === ProposalType.PROPOSAL_UPDATE_MARKET && (
<section> <section>
<SubHeading title={t('liquidityVotes')} /> <SubHeading title={t('liquidityVotes')} />
<p> <p data-testid="liquidity-votes-status">
<span> <span>
<CurrentProposalStatus proposal={proposal} /> <CurrentProposalStatus proposal={proposal} />
</span> </span>
@ -105,7 +105,7 @@ export const VoteDetails = ({
)} )}
<section data-testid="votes-table"> <section data-testid="votes-table">
<SubHeading title={t('tokenVotes')} /> <SubHeading title={t('tokenVotes')} />
<p> <p data-testid="token-votes-status">
<span> <span>
<CurrentProposalStatus proposal={proposal} /> <CurrentProposalStatus proposal={proposal} />
</span> </span>

View File

@ -19,6 +19,7 @@ import { addCreateMarket } from './lib/commands/create-market';
import { addConnectPublicKey } from './lib/commands/add-connect-public-key'; import { addConnectPublicKey } from './lib/commands/add-connect-public-key';
import { addVegaWalletSubmitProposal } from './lib/commands/vega-wallet-submit-proposal'; import { addVegaWalletSubmitProposal } from './lib/commands/vega-wallet-submit-proposal';
import { addGetNodes } from './lib/commands/get-nodes'; import { addGetNodes } from './lib/commands/get-nodes';
import { addVegaWalletSubmitLiquidityProvision } from './lib/commands/vega-wallet-submit-liquidity-provision';
addGetTestIdcommand(); addGetTestIdcommand();
addSlackCommand(); addSlackCommand();
@ -39,6 +40,7 @@ addMockTransactionResponse();
addCreateMarket(); addCreateMarket();
addConnectPublicKey(); addConnectPublicKey();
addVegaWalletSubmitProposal(); addVegaWalletSubmitProposal();
addVegaWalletSubmitLiquidityProvision();
export { mockConnectWallet } from './lib/commands/vega-wallet-connect'; export { mockConnectWallet } from './lib/commands/vega-wallet-connect';
export type { onMessage } from './lib/mock-ws'; export type { onMessage } from './lib/mock-ws';

View File

@ -0,0 +1,67 @@
import { PeggedReference } from '@vegaprotocol/types';
import type { LiquidityProvisionSubmission } from '@vegaprotocol/wallet';
import { createWalletClient, sendVegaTx } from '../capsule/wallet-client';
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable<Subject> {
VegaWalletSubmitLiquidityProvision(
marketId: string,
amount: string
): void;
}
}
}
export const addVegaWalletSubmitLiquidityProvision = () => {
Cypress.Commands.add(
'VegaWalletSubmitLiquidityProvision',
(marketId, amount) => {
const vegaWalletUrl = Cypress.env('VEGA_WALLET_URL');
const token = Cypress.env('VEGA_WALLET_API_TOKEN');
const vegaPubKey = Cypress.env('VEGA_PUBLIC_KEY');
const liquidityProvisionTx: LiquidityProvisionSubmission = {
liquidityProvisionSubmission: {
marketId: marketId,
commitmentAmount: amount,
fee: '0.001',
buys: [
{
offset: '10',
proportion: '1',
reference: PeggedReference.PEGGED_REFERENCE_MID,
},
{
offset: '12',
proportion: '2',
reference: PeggedReference.PEGGED_REFERENCE_MID,
},
],
sells: [
{
offset: '10',
proportion: '2',
reference: PeggedReference.PEGGED_REFERENCE_MID,
},
{
offset: '12',
proportion: '2',
reference: PeggedReference.PEGGED_REFERENCE_MID,
},
],
},
pubKey: vegaPubKey,
propagate: true,
};
createWalletClient(vegaWalletUrl, token);
cy.highlight('Submitting liquidity provision');
sendVegaTx(vegaPubKey, liquidityProvisionTx);
}
);
};

View File

@ -1,5 +1,25 @@
import { WalletClientError } from '@vegaprotocol/wallet-client'; import { WalletClientError } from '@vegaprotocol/wallet-client';
import type * as Schema from '@vegaprotocol/types'; import type * as Schema from '@vegaprotocol/types';
import type { PeggedReference } from '@vegaprotocol/types';
export interface LiquidityProvisionSubmission {
liquidityProvisionSubmission: LiquidityProvisionBody;
pubKey: string;
propagate: boolean;
}
export interface LiquidityProvisionBody {
marketId: string;
commitmentAmount: string;
fee: string;
buys?: PeggedOrders[];
sells?: PeggedOrders[];
}
export interface PeggedOrders {
offset: string;
proportion: string;
reference: PeggedReference;
}
export interface DelegateSubmissionBody { export interface DelegateSubmissionBody {
delegateSubmission: { delegateSubmission: {
@ -336,7 +356,8 @@ export type Transaction =
| OrderAmendmentBody | OrderAmendmentBody
| ProposalSubmissionBody | ProposalSubmissionBody
| BatchMarketInstructionSubmissionBody | BatchMarketInstructionSubmissionBody
| TransferBody; | TransferBody
| LiquidityProvisionSubmission;
export const isWithdrawTransaction = ( export const isWithdrawTransaction = (
transaction: Transaction transaction: Transaction