diff --git a/non-protocol-specs/0003-NP-LIMI-limits_aka_training_wheels.md b/non-protocol-specs/0003-NP-LIMI-limits_aka_training_wheels.md index 6761e86af..04a2eab50 100644 --- a/non-protocol-specs/0003-NP-LIMI-limits_aka_training_wheels.md +++ b/non-protocol-specs/0003-NP-LIMI-limits_aka_training_wheels.md @@ -134,7 +134,7 @@ This is primarily for liquidity providers and other sophisticated participants a - An ETH address that is listed on the smart contract as exempt can deposit more than `max lifetime deposit` - Any ETH address can use a method on the smart contract to add or remove itself (own ETH address) from the exemption list 1. `max lifetime deposit` can be updated per asset via an Ethereum transaction (0003-NP-LIMI-003) -1. Validators can, via multisig, stop and recommence processing bridge transactions (0003-NP-LIMI-004) +1. Validators can, via multisig, stop and recommence processing bridge transactions on any of the bridges (0003-NP-LIMI-007) - A representative set of validators can produce a multisig transaction that stops all future deposits and withdrawals - A representative set of validators can produce a multisig transaction that allows the bridge to resume processing future deposits and withdrawals - All withdrawals that are submitted while the bridge is 'stopped' are rejected diff --git a/protocol/0027-ASSP-asset_proposal.md b/protocol/0027-ASSP-asset_proposal.md index 26455df6e..2c5af4ebe 100644 --- a/protocol/0027-ASSP-asset_proposal.md +++ b/protocol/0027-ASSP-asset_proposal.md @@ -22,13 +22,15 @@ When exactly the nodes must have approved or not signalled approval of the asset As detailed above, the validators will check the validity of the details supplied by the asset proposer. The validation occurs before the `validationTimestamp` provided in the `ProposalTerms`. The following checks should be applied: -### ERC20 assets +### ERC20 assets on any Ethereum VM compatible chain supporting Ethereum RPC -- The contract address provided must point to an ERC20 asset on the [bridged Ethereum network](./0031-ETHB-ethereum_bridge_spec.md) -- The contract must not already have an existing asset accepted on the Vega network (note: another _proposal_ could exist for the same asset) +- The proposal must point to an id of an Ethereum VM compatible chain supporting Ethereum RPC that Vega network recognises +- The contract address provided must point to an ERC20 asset on the [bridged Ethereum VM compatible chain supporting Ethereum RPC network](./0031-ETHB-ethereum_bridge_spec.md) +- The chain id and contract pair must not already have an existing asset accepted on the Vega network (note: another _proposal_ could exist for the same asset) - The name must strictly match the name in the ERC20 contract (e.g. `Wrapped ether`) - The symbol must strictly match the symbol (e.g. `WETH`) + ## Enabling a new asset on the bridge Once the proposal is accepted, validators will produce a bundle (e.g. transaction plus signature/s) for submission to the asset's originating blockchain. Vega nodes will make this bundle available via an API. @@ -77,7 +79,8 @@ message ERC20 { // contract address of an ERC20 token string contractAddress = 1; string maximumLifetimeDeposit = 2; // note that e.g: 100000 in here will be interpreted against the asset decimals - string withdrawalDelayThreshold = 3; // this is will be interpreted against the asset decimals + string withdrawalDelayThreshold = 3; // this is will be interpreted against the asset decimals + string chain_id = 4; // this is the ID of the chain the asset's contract address is from } message AssetSource { @@ -163,18 +166,21 @@ This must be an integer strictly greater than `0`. ### User actions -- As a user I can submit a new proposal asset to be used in vega (0027-ASSP-001) +- As a user I can submit a new proposal asset to be used in vega for any EVM-ERPC asset bridge (0027-ASSP-034) - As a user I can vote for an asset proposal. (0027-ASSP-002) -- As a user, original submitter of the asset, I can call the node to get a signature of the asset, so I can send it to the asset bridge, and whitelist the asset. (0027-ASSP-003) +- As a user, original submitter of the asset, I can call the node to get a signature of the asset, so I can send it to the asset bridge, and whitelist the asset on any asset bridge (0027-ASSP-035) - `quantum` is a required parameter (0027-ASSP-004) - If an update asset proposal passed and it changes `quantum` _only_ then this new value becomes used immediately on enactment. (0027-ASSP-025) +- As a user if I submit a new proposal asset for an ERC20 asset without specifying a chain-id, the proposal is rejected (0027-ASSP-031) +- As a user if I submit a new proposal asset for an ERC20 asset with a chain-id that does not correspond to any bridge, the proposal is rejected (0027-ASSP-032) +- As a user if, I can see the chain-id an ERC20 asset originates on via a data node API (0027-ASSP-033) ### Node actions -- As a node, when a new asset proposal is emitted, I can validate the asset with it's chain, and send the result of the validation through the chain to the other nodes (first phase proposal) (0027-ASSP-005) -- As a node, when a new asset is accepted through governance, I can sign a payload to the user so they can whitelist the asset with the bridge (0027-ASSP-006) -- As a node, I receive events from the external blockchain queue, that confirm the asset is enabled in the bridge. (0027-ASSP-007) -- As a node, when an existing asset is modified through governance changing any one of `maximumLifetimeDeposit` or `withdrawalDelayThreshold`, emit a signed a payload to the world so that they can update the corresponding parameters on the bridge (0027-ASSP-008) +- As a node, when a new asset proposal is emitted, I can validate the asset with its chain, and send the result of the validation through the chain to the other nodes (first phase proposal) on any asset bridge (0027-ASSP-027) +- As a node, when a new asset from any EVM/ERPC bridge is accepted through governance, I can sign a payload to the user so they can whitelist the asset on the bridge contract on the appropriate chain (0027-ASSP-028) +- As a node, I receive events from the external blockchain queues for all the registered EVM/ERPC chains, that confirm the asset is enabled on the relevant chain bridge contract (0027-ASSP-029) +- As a node, when an existing asset is modified through governance changing any one of `maximumLifetimeDeposit` or `withdrawalDelayThreshold`, emit a signed a payload to the world so that they can update the corresponding parameters on the EVM/ERPC chain the asset is bridged from (0027-ASSP-030) ### Validation @@ -201,4 +207,3 @@ This must be an integer strictly greater than `0`. - There is an asset `X` on vega / bridge with withdrawal delay threshold `t1`. Withdrawal in asset `X` below `t1` has no delay i.e. can be finalised on Ethereum as soon as the withdrawal bundle is received. A withdrawal in asset `X` with amount greater than or equal to `t1` will be rejected by the bridge before time `bundle creation + delay` but can be finalised after `delay` time passes from bundle creation. Here `delay` is the global bridge delay parameter. (0027-ASSP-023) - There is an asset `X` on vega / bridge with withdrawal delay threshold `t1`. An asset update proposal is submitted to change these to `t2`; it passes voting and is submitted to Ethereum bridge contract. The new thresholds now apply i.e. withdrawal in asset `X` below `t2` has no delay i.e. can be finalised on Ethereum as soon as the withdrawal bundle is received. A withdrawal in asset `X` with amount greater than or equal to `t2` will be rejected by the bridge before time `bundle creation + delay` but can be finalised after `delay` time passes from bundle creation. Here `delay` is the global bridge delay parameter. (0027-ASSP-024) - diff --git a/protocol/0031-ETHB-ethereum_bridge_spec.md b/protocol/0031-ETHB-ethereum_bridge_spec.md index 8acda13db..e3795e69d 100644 --- a/protocol/0031-ETHB-ethereum_bridge_spec.md +++ b/protocol/0031-ETHB-ethereum_bridge_spec.md @@ -138,13 +138,13 @@ This example connects the network to Ropsten: ### Deposit - ERC-20 smart contract (This can be repeated for many token standards - NFTs and crypto items will be more complex): - - An Ethereum Address can call the deposit function and successfully deposit any token that is listed via `list_asset` (0031-ETHB-008) + - A wallet address can call the deposit function on the bridge contract on any EVM/ERPC chain on which the bridge contract is deployed and successfully deposit any token that is listed via `list_asset` on the asset bridge on the said chain (0031-ETHB-084). - A deposit call with a removed token `remove_asset` is rejected (0031-COSMICELEVATOR-009) ### Withdraw - ERC-20 smart contract specific requirements: - - A valid multisig bundle can be passed to the withdraw function to successfully withdraw an ERC-20 asset (0031-ETHB-013) + - A valid multisig bundle can be passed to the withdraw function to successfully withdraw an ERC-20 asset to a wallet address on any EVM/ERPC chain asset bridge (0031-ETHB-085) - An invalid multisig bundle will be rejected from withdraw (0031-ETHB-014) ### Allowlist a token (by eth address) diff --git a/protocol/0069-VCBS-validators_chosen_by_stake.md b/protocol/0069-VCBS-validators_chosen_by_stake.md index 9e7267da0..e88693f20 100644 --- a/protocol/0069-VCBS-validators_chosen_by_stake.md +++ b/protocol/0069-VCBS-validators_chosen_by_stake.md @@ -84,30 +84,58 @@ Basic vega chain liveness criteria is covered in their [performance score](./006 ## Verifying Ethereum (and later other chain) integration -In order to be considered for promotion from ersatz validator to Tendermint validator, an ersatz validator must prove itself to be reliable. This is measured by ensuring their reliability in forwarding [Ethereum events](./0036-BRIE-event_queue.md). -A network parameter, `network.validators.minimumEthereumEventsForNewValidator`, is used to set the acceptable minimum count of times that an ersatz validator was the first to forward a subsequently accepted Ethereum event at least `network.validators.minimumEthereumEventsForNewValidator` times. +In order to be considered for promotion from ersatz validator to Tendermint validator, an ersatz validator must prove itself to be reliable. This is measured by ensuring their reliability in forwarding [Chain events](./0036-BRIE-event_queue.md). +A network parameter, `network.validators.minimumEthereumEventsForNewValidator`, is used to set the acceptable minimum count of times that an ersatz validator was the first to forward a subsequently accepted Ethereum event at least `network.validators.minimumEthereumEventsForNewValidator` times. An ersatz node will have to forward this number of events for each bridge. ## Multisig updates (and multisig weight updates if those are used) -Vega will know the initial multisig signer list (and weights) and watch for `signer added` and `signer removed` events to track which ethereum keys are present on multisig. +Vega will know the initial multisig signer list (and weights) and watch for `signer added` and `signer removed` events to track which ethereum keys are present on the multisig on every registered EVM/ERPC chain. -Once (if) the ethereum multisig contract supports validator weights the vega node will watch for Ethereum events announcing the weight changing. -Thus for each validator that is on the multisig contract it will know the validator score (weight) the ethereum multisig is using. +Once (if) the multisig contracts supports validator weights the vega node will watch for Ethereum events announcing the weight changing. +Thus for each validator that is on each multisig contract it will know the validator score (weight) the multisig is using. -We will have `network.validators.multisig.numberOfSigners` represented on the multisig (currently `13`) but this could change. +We will have `network.validators.multisig.numberOfSigners` represented on each multisig. Note that `network.validators.multisig.numberOfSigners` must always be less than or equal to `network.validators.tendermint.number`. -In the reward calculation for the top `network.validators.multisig.numberOfSigners` by `validator_score` (as seen on VEGA) use `min(validator_score, ethereum_multisig_weight)` when calculating the final reward with `0` for those who are in the top `network.validators.multisig.numberOfSigners` by score but *not* on the multisig contract. +In the reward calculation for the top `network.validators.multisig.numberOfSigners` by `validator_score` (as seen on VEGA) use `min(validator_score, chain_1_multisig_weight, ..., chain_n_multisig_weight)`, with `n` representing the number of registered EVM/ERPC chains for assets, when calculating the final reward with `0` for those who are in the top `network.validators.multisig.numberOfSigners` by score but *missing* from the multisig contract on any of the `n` registered asset chains. -Thus a validator who is not there but should be has incentive to pay gas to update the multisig. Moreover a validator who's score has gone up substantially will want to do so as well. +Thus a validator who is not there but should be has incentive to pay gas to update each multisig. Moreover a validator who's score has gone up substantially will want to do so as well. -As a consequence, if a potential validator joined the Vega chain validators but has *not* updated the Multisig members (and/or weights) then at the end of the epoch their score will be `0`. They will not get any rewards. +As a consequence, if a potential validator joined the Vega chain validators but has *not* updated the Multisig members (and/or weights) for each bridge, then at the end of the epoch their score will be `0`. They will not get any rewards. -In the case where a node is removed due reduced delegation, or due to not meeting self-delegation criteria, or due to lack of performance, or due to a reduction in the value of `network.validators.tendermint.number`, the onus is on all of the remaining validators to remove the demoted member from the Multisig contract. They are incentivised to do so by all receiving a `validator_score` of `0` *in the reward calculation* until the excess member is removed. +In the case where a node is removed due reduced delegation, or due to not meeting self-delegation criteria, or due to lack of performance, or due to a reduction in the value of `network.validators.tendermint.number`, the onus is on all of the remaining validators and the community to remove the demoted member from all Multisig contracts. They are incentivised to do so by all receiving a `validator_score` of `0` *in the reward calculation* until the excess member is removed from each bridge. Bear in mind that currently in this situation the unpaid rewards stay in the reward pool and eventually everything gets distributed at the end of any epoch where the multisig is updated. Note that this could become obsolete if a future version of the protocol implements threshold signatures or another method that allows all validators to approve Ethereum actions. + +## Issuing signatures bundles to update Multisig contracts + +When a nodes is promoted or demoted from the tendermint validator set the multisig control contracts on each bridge should be updated to reflect the new set. To be able to update the signers on the multisig control contract a signature bundle authorising the addition or removal of a signer is required containing a quorum of signatures from those already on the multisig control contract. + +As rewards are withheld from all parties who have staked and delegated to the Vega network, any party is allowed to request a signature bundle to resolve the multisig contract and continue receiving rewards. This can be done by sending in a transaction to the network containing the following information: + +```json +{ + "submitter": "abc", # the Ethereum address that will submit the transaction to the multisig contract + "node_id": "xyz", # the node ID who needs to be added or removed + "type": "add/remove", # whether the node needs to be added or removed + "chain_id": "1", # the ID of the EVM chain the signature bundle is for +} +``` + +Then result from a successful submission will be the generation of a signature bundle made available via a data node. + +A transaction to issue signatures must fail if: + +- the request *does not* correspond to a validator the needs adding/removing from the contract +- the given chain-id does not belong to any bridge + +Once a validator who needs adding/removing from the contract has been added/removed (or no longer needs to be added or removed) it must not be possible to request more signature bundles for it. + +All signature bundles for a particular adding/removal event *must* use the same nonce. For example if validator `v` is promoted and needs to be added to the contract, when three different parties submit transactions to issue signatures, each of their bundles should use the same nonce. This necessary so that ones one bundle has been used, the other 2 are now defunct. + + ## Ersatz/Standby validators In addition to the normal validators, there is an additional set of Ersatz validators (also referred to as Standby Validators) as defined by the corresponding network parameter. These are validators that do not contribute to the chain, but are on standby to jump in if a normal validator drops off. The network will have @@ -137,7 +165,7 @@ is a out-of-the ordinary event and should be logged. ### Multisig for Ersatz validators -At this point, Ersatz validators are not part of the Multisig. +At this point, Ersatz validators are not part of any Multisig. ## Network Parameters @@ -150,6 +178,8 @@ At this point, Ersatz validators are not part of the Multisig. |`network.validators.multisig.numberOfSigners` | String (integer) | 9 | Currently set to the number of validators on the network. In future will be used to scale multisig Validator participation. | |`network.validators.ersatz.rewardFactor` | String (float) | 0.2 | Scales down [the rewards](./0069-VCBS-validators_chosen_by_stake.md#ersatz-validators) of ersatz validators relative to actual validators | |`network.validators.ersatz.multipleOfTendermintValidators` | String (integer) | 2 | Used to [calculate the number](./0069-VCBS-validators_chosen_by_stake.md#ersatz-validators) of ersatz Validators that will earn rewards | +|`spam.protection.minMultisigUpdates` | String (integer) | 5 | Minimum number of staked tokens a party must have to be able to submit a transaction to issue signatures | +|`spam.protection.max.MultisigUpdates` | String (integer) | 5 | Maximum number of times per epoch a party can submit a transaction to issue signatures | ## Acceptance criteria @@ -191,9 +221,9 @@ At this point, Ersatz validators are not part of the Multisig. 1. Verify that for all ersatz validators their multisig score is 1 (0069-VCBS-010) 1. Tendermint validators excess signature (0069-VCBS-011): - Setup a network with 5 Tendermint validators but with only 4 validators that have sufficient self-delegation. Call the one without enough self-delegation Bob. - - Announce a new node (Alice) and self-delegate to them, allow some time to replace the validator with no self-delegation (Bob) as a Tendermint validator by Alice. Note: At this point the signature of Bob IS still on the multisig contract. + - Announce a new node (Alice) and self-delegate to them, allow some time to replace the validator with no self-delegation (Bob) as a Tendermint validator by Alice. Note: At this point the signature of Bob IS still on all the multisig contracts. - Transfer 1000 tokens to the VEGA reward account. - - Verify that at the end of the epoch all of the Tendermint validators should have a multisig score = 0 since Bob is still on the contract. + - Verify that at the end of the epoch all of the Tendermint validators should have a multisig score = 0 since Bob is still on all contracts. 1. Tendermint validators missing signature test 1 (0069-VCBS-012): - Setup a network with 4 Tendermint validators with self-delegation and number of Tendermint validators network parameter set to 5. - **Additional setup:** ensure that the network parameter `network.validators.multisig.numberOfSigners` is set to **5**. @@ -221,8 +251,21 @@ At this point, Ersatz validators are not part of the Multisig. - Verify that the joining validator would have a multisig score of 1 and therefore gets a reward. 1. One of the top validators is not registered with the multisig contract (0069-VCBS-051): - Run a Vega network where a validator joins and gets a lot delegated in order for it to become one of the top `network.validators.multisig.numberOfSigners` - - Ensure its ethereum key is **NOT** put on the multisig contract. + - Ensure its ethereum key is **NOT** put on any of the multisig contract. - Verify the validator has 0 for their multisig score and receives no staking reward. +1. All multisig contracts must be updated for non-zero multisig scores (0069-VCBS-092) + - Arrange a network with N validators and 1 ersatz validator. + - Set `network.validators.multisig.numberOfSigners` = N. + - Arrange for one of the validators to be demoted and the ersatz validator to be promoted. + - Assert that since the demoted validator is still on the multisigs, all tendermint validators should have a multisig score of `0` + - Remove the demoted validator from only one multisig contracts + - Assert that all tendermint validators have a multisig score of `0` + - Remove the demoted validator the remaining multisig contracts + - Assert that all tendermint validators *except the promoted validator* should have a multisig score of `1` + - Add the promoted validator to only one of the multisig contracts + - Assert that the promoted validator still has a multisig score of `0` + - Add the promoted validator to all of the multisig contracts + - Assert that the promoted validator now has a multisig score of `1` #### Validator Score @@ -518,18 +561,17 @@ Setup a network with 6 nodes (3 validators, 2 ersatz validators, 1 pending valid - Arrange a network with N validators and 1 ersatz validator. - Set `network.validators.multisig.numberOfSigners` = N. - Arrange for one of the validators to be demoted and the ersatz validator to be promoted. - - Update the multisig contract by removing the demoted validator, and adding the new tendermint validator. + - Update the multisig contract on all bridges by removing the demoted validator, and adding the new tendermint validator. - Verify that rewards are paid out at the end of the epoch. 1. No rewards paid out if multisig not updated. Rewards continued when fixed. (0069-VCBS-067) - Arrange a network with N validators and 1 ersatz validator. - Set `network.validators.multisig.numberOfSigners` = N. - - Arrange for one of the validators to be demoted and the ersatz validator to be promoted. - Verify that no rewards are paid out on the first epoch. - - Update the multisig contract by removing the demoted validator, and adding the new tendermint validator. + - Update all multisig contracts by removing the demoted validator, and adding the new tendermint validator. - Verify that rewards are paid out at the end of the epoch. -1. Any vega key with number of governance tokens more than or equal to `spam.protection.minMultisigUpdates` or a vega key that belongs to a validator can submit a request to the vega network to obtain the signature bundle that would update the ethereum multisig signers to be the ethereum keys of the current consensus (tendermint) validators up to `network.validators.multisig.numberOfSigners`. This request can only be submitted once per epoch per vega key. Once multisig uses weights it will also include the correct weights. (0069-VCBS-068) -1. Replace a validator with a new node via promotion/demotion. Ensure that rewards are paid out at the end of the epoch if the multisig is updated to match the new validator. (0069-VCBS-071) +1. Any vega key with number of governance tokens more than or equal to `spam.protection.minMultisigUpdates` or a vega key that belongs to a validator can submit a request to the vega network to obtain the signature bundle that would update the multisig signers to be the keys of the current consensus (tendermint) validators up to `network.validators.multisig.numberOfSigners`. This request can only be submitted `spam.protection.max.MultisigUpdates` times per epoch per vega key per registered EVM/ERPC asset chain (alternatively the request will provide the update bundles for all the chains). Once multisig uses weights it will also include the correct weights for all multisig contracts. (0069-VCBS-094) +1. Replace a validator with a new node via promotion/demotion. Ensure that rewards are paid out at the end of the epoch if all multisigs are updated to match the new validator. (0069-VCBS-091) ### Re-Issuing Signature Bundles by non Validators @@ -553,3 +595,12 @@ Setup a network with 6 nodes (3 validators, 2 ersatz validators, 1 pending valid 1. Issue 5 requests from a vega key in the same block, 4 of which with invalid signatures. Verify that only the one with the correct signature is passed to consensus, and is properly executed. (0069-VCBS-087) + +1. After a node has been promoted, issue a request for a signature to add it to the multisig control contract but provide a chain-id that does not correspond to any bridge. It should fail. +(0069-VCBS-089) + +1. After a node has been demoted, issue a request for a signature to remove it to the multisig control contract but provide a chain-id that does not correspond to any bridge. It should fail. +(0069-VCBS-090) + +1. After a successful transaction to issue signatures, the data node API containing the signature bundles also includes the chain-id for the multisig contract it corresponds to. +(0069-VCBS-093) diff --git a/protocol/0080-SPOT-product_builtin_spot.md b/protocol/0080-SPOT-product_builtin_spot.md index 3ef35458e..a5e396362 100644 --- a/protocol/0080-SPOT-product_builtin_spot.md +++ b/protocol/0080-SPOT-product_builtin_spot.md @@ -133,3 +133,4 @@ Price-monitoring auctions are still required and should be implemented following 1. If the fee rates change for any reason within an auction, when the auction exits the amount required to cover fees must be recalculated. If a party does not have enough funds to cover the increase their order should be stopped with a clear return code. (0080-SPOT-021). 1. When exiting an auction, for any orders that are still open, the funds held in the parties' holding_account to cover potential fees can be released to their respective general_account, so that the remaining amount in the holding_account is only sufficient to cover the value of the order.(0080-SPOT-020). 1. Spot governance proposal fails with asset error, when quote_asset and base_asset has same assets. (0080-SPOT-022). +1. A `Spot` market can be created for a `quote_asset` / `base_asset` where each asset exists on a different originating chain i.e one asset is on one asset bridge and another asset is from another asset bridge. As a user I can then deposit one asset through one bridge, swap it, and withdraw the other asset through any other bridge (0080-SPOT-023) diff --git a/protocol/features.json b/protocol/features.json index c83a0e9e3..28c27f6f2 100644 --- a/protocol/features.json +++ b/protocol/features.json @@ -347,6 +347,30 @@ "milestone": "colosseo", "acs": ["0012-POSR-030"] }, + "New asset bridge": { + "milestone": "colosseo", + "acs": [ + "0027-ASSP-027", + "0027-ASSP-028", + "0027-ASSP-029", + "0027-ASSP-030", + "0027-ASSP-031", + "0027-ASSP-032", + "0027-ASSP-033", + "0027-ASSP-034", + "0027-ASSP-035", + "0031-ETHB-084", + "0031-ETHB-085", + "0069-VCBS-089", + "0069-VCBS-090", + "0069-VCBS-091", + "0069-VCBS-092", + "0069-VCBS-093", + "0069-VCBS-094", + "0080-SPOT-023", + "0003-NP-LIMI-007" + ] + }, "Unknown": { "milestone": "unknown", "acs": [] diff --git a/wordlist.txt b/wordlist.txt index e6c46db2b..8001e5979 100644 --- a/wordlist.txt +++ b/wordlist.txt @@ -9,6 +9,7 @@ allowlisted antiwhaling API APIs +Arbitrum AST asynchrony atomicity @@ -92,6 +93,7 @@ ERC ERC-1155 ERC-20 ERC-721 +ERPC ETH ETH's ETHB @@ -185,6 +187,7 @@ misconfiguration MTM mu multisig +multisigs MultisigControl multisignature NFTs @@ -322,6 +325,7 @@ vegawallet verifiably verifier visor +VM VW VWAP walkthrough