From 884b55e415c4c079d89752bea7c61b85809c9ef0 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Wed, 27 Sep 2023 14:34:27 +0300 Subject: [PATCH] add historical vp checks on schedules add/remove --- .../tge.investors_vesting_vault.test.ts | 663 +++++++++++++----- 1 file changed, 489 insertions(+), 174 deletions(-) diff --git a/src/testcases/parallel/tge.investors_vesting_vault.test.ts b/src/testcases/parallel/tge.investors_vesting_vault.test.ts index a69029a6..e255f01a 100644 --- a/src/testcases/parallel/tge.investors_vesting_vault.test.ts +++ b/src/testcases/parallel/tge.investors_vesting_vault.test.ts @@ -107,7 +107,7 @@ describe('Neutron / TGE / Investors vesting vault', () => { describe('prepare investors vesting vault', () => { test('create vesting accounts', async () => { - const execRes = await cmInstantiator.executeContract( + await cmInstantiator.executeContract( contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], JSON.stringify({ register_vesting_accounts: { @@ -133,7 +133,6 @@ describe('Neutron / TGE / Investors vesting vault', () => { }), [{ denom: NEUTRON_DENOM, amount: totalVestingAmount.toString() }], ); - expect(execRes.code).toBe(0); }); test('check unclaimed amounts', async () => { await neutronChain.blockWaiter.waitBlocks(1); @@ -171,36 +170,39 @@ describe('Neutron / TGE / Investors vesting vault', () => { }); }); + // vars for init state + let user1VpInit: VotingPowerResponse; + let user2VpInit: VotingPowerResponse; + let totalVpInit: VotingPowerResponse; + let heightInit: number; describe('voting power', () => { describe('check initial voting power', () => { test('total power at height', async () => { - const res = await neutronChain.queryContract( + heightInit = await env.getHeight(neutronChain.sdk); + totalVpInit = await totalPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { total_power_at_height: {} }, + heightInit, ); - expect(+res.power).toBe(totalVestingAmount); + expect(+totalVpInit.power).toBe(totalVestingAmount); }); test('user1 power at height', async () => { - const res = await neutronChain.queryContract( + user1VpInit = await votingPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { - voting_power_at_height: { - address: cmUser1.wallet.address.toString(), - }, - }, + cmUser1.wallet.address.toString(), + heightInit, ); - expect(+res.power).toBe(user1VestingAmount); + expect(+user1VpInit.power).toBe(user1VestingAmount); }); test('user2 power at height', async () => { - const res = await neutronChain.queryContract( + user2VpInit = await votingPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { - voting_power_at_height: { - address: cmUser2.wallet.address.toString(), - }, - }, + cmUser2.wallet.address.toString(), + heightInit, ); - expect(+res.power).toBe(user2VestingAmount); + expect(+user2VpInit.power).toBe(user2VestingAmount); }); }); @@ -212,7 +214,7 @@ describe('Neutron / TGE / Investors vesting vault', () => { await neutronChain.blockWaiter.waitBlocks(1); // so it's before claim for sure }); test('user1 partial claim', async () => { - const execRes = await cmUser1.executeContract( + await cmUser1.executeContract( contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], JSON.stringify({ claim: { @@ -220,51 +222,43 @@ describe('Neutron / TGE / Investors vesting vault', () => { }, }), ); - expect(execRes.code).toBe(0); await neutronChain.blockWaiter.waitBlocks(1); - const res = await neutronChain.queryContract( + const res = await votingPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { - voting_power_at_height: { - address: cmUser1.wallet.address.toString(), - }, - }, + cmUser1.wallet.address.toString(), ); expect(+res.power).toBe(user1VestingAmount - user1PartialClaim); }); test('total voting power check after user1 partial claim', async () => { - const res = await neutronChain.queryContract( + const res = await totalPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { total_power_at_height: {} }, ); expect(+res.power).toBe(totalVestingAmount - user1PartialClaim); }); test('user2 full claim', async () => { - const execRes = await cmUser2.executeContract( + await cmUser2.executeContract( contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], JSON.stringify({ claim: {}, }), ); - expect(execRes.code).toBe(0); await neutronChain.blockWaiter.waitBlocks(1); - const res = await neutronChain.queryContract( + const res = await votingPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { - voting_power_at_height: { - address: cmUser2.wallet.address.toString(), - }, - }, + cmUser2.wallet.address.toString(), ); expect(+res.power).toBe(0); }); test('total voting power check after user2 full claim', async () => { - const res = await neutronChain.queryContract( + const res = await totalPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { total_power_at_height: {} }, ); expect(+res.power).toBe( totalVestingAmount - user1PartialClaim - user2VestingAmount, @@ -272,29 +266,25 @@ describe('Neutron / TGE / Investors vesting vault', () => { }); test('user1 full claim', async () => { - const execRes = await cmUser1.executeContract( + await cmUser1.executeContract( contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], JSON.stringify({ claim: {}, }), ); - expect(execRes.code).toBe(0); await neutronChain.blockWaiter.waitBlocks(1); - const res = await neutronChain.queryContract( + const res = await votingPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { - voting_power_at_height: { - address: cmUser1.wallet.address.toString(), - }, - }, + cmUser1.wallet.address.toString(), ); expect(+res.power).toBe(0); }); test('total voting power check after full claim', async () => { - const res = await neutronChain.queryContract( + const res = await totalPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { total_power_at_height: {} }, ); expect(+res.power).toBe(0); }); @@ -305,33 +295,28 @@ describe('Neutron / TGE / Investors vesting vault', () => { // at that point regardless of the following claim calls and TWAP changes. describe('check voting power before claim', () => { test('total power', async () => { - const res = await neutronChain.queryContract( + const res = await totalPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { total_power_at_height: { height: heightBeforeClaim } }, + heightBeforeClaim, ); expect(+res.power).toBe(totalVestingAmount); }); test('user1 power', async () => { - const res = await neutronChain.queryContract( + const res = await votingPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { - voting_power_at_height: { - address: cmUser1.wallet.address.toString(), - height: heightBeforeClaim, - }, - }, + cmUser1.wallet.address.toString(), + heightBeforeClaim, ); expect(+res.power).toBe(user1VestingAmount); }); test('user2 power', async () => { - const res = await neutronChain.queryContract( + const res = await votingPowerAtHeight( + neutronChain, contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], - { - voting_power_at_height: { - address: cmUser2.wallet.address.toString(), - height: heightBeforeClaim, - }, - }, + cmUser2.wallet.address.toString(), + heightBeforeClaim, ); expect(+res.power).toBe(user2VestingAmount); }); @@ -339,69 +324,259 @@ describe('Neutron / TGE / Investors vesting vault', () => { }); }); + /* + Here we test how vesting account addition/removal affect current and historical voting power + The flow is as follows: + 1. record voting power before vesting account additions/removals; + 2. add a vesting account for both user1 and user2 (endPoint=vestingAmount); + 3. record voting power and make sure it's changed properly; + 4. make sure historical voting power (cmp to init and p.1) hasn't changed; + 5. remove a vesting account for user2 (vestingAmount); + 6. make sure voting power has changed properly; + 7. make sure historical voting power (cmp to init, p.1 and p.3) hasn't changed; + */ describe('manage vesting accounts', () => { const vestingAmount = 500_000_000; - test('create a new vesting account', async () => { - const execRes = await cmInstantiator.executeContract( - contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], - JSON.stringify({ - register_vesting_accounts: { - vesting_accounts: [ - types.vestingAccount(cmUser1.wallet.address.toString(), [ - types.vestingSchedule( - types.vestingSchedulePoint(0, vestingAmount.toString()), - ), - ]), + // vars for state before voting accounts added + let user1VpBeforeAdd: VotingPowerResponse; + let user2VpBeforeAdd: VotingPowerResponse; + let totalVpBeforeAdd: VotingPowerResponse; + let heightBeforeAdd: number; + // vars for state after voting accounts added + let user1VpAfterAdd: VotingPowerResponse; + let user2VpAfterAdd: VotingPowerResponse; + let totalVpAfterAdd: VotingPowerResponse; + let heightAfterAdd: number; + describe('add vesting accounts', () => { + test('record current voting power', async () => { + heightBeforeAdd = await env.getHeight(neutronChain.sdk); + user1VpBeforeAdd = await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightBeforeAdd, + ); + user2VpBeforeAdd = await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightBeforeAdd, + ); + totalVpBeforeAdd = await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightBeforeAdd, + ); + }); + + describe('register vesting accounts', () => { + test('execute register_vesting_accounts', async () => { + await cmInstantiator.executeContract( + contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], + JSON.stringify({ + register_vesting_accounts: { + vesting_accounts: [ + types.vestingAccount(cmUser1.wallet.address.toString(), [ + types.vestingSchedule( + types.vestingSchedulePoint(0, vestingAmount.toString()), + ), + ]), + types.vestingAccount(cmUser2.wallet.address.toString(), [ + types.vestingSchedule( + types.vestingSchedulePoint(0, vestingAmount.toString()), + ), + ]), + ], + }, + }), + [ + { + denom: NEUTRON_DENOM, + amount: (2 * vestingAmount).toString(), + }, ], - }, - }), - [{ denom: NEUTRON_DENOM, amount: vestingAmount.toString() }], - ); - expect(execRes.code).toBe(0); - await neutronChain.blockWaiter.waitBlocks(1); - const currentHeight = await env.getHeight(neutronChain.sdk); - expect( - await neutronChain.queryContract( - contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], - { - historical_extension: { - msg: { - unclaimed_amount_at_height: { - address: cmUser1.wallet.address.toString(), - height: currentHeight, + ); + await neutronChain.blockWaiter.waitBlocks(1); + }); + + test('check available amounts', async () => { + const currentHeight = await env.getHeight(neutronChain.sdk); + expect( + await neutronChain.queryContract( + contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], + { + historical_extension: { + msg: { + unclaimed_amount_at_height: { + address: cmUser1.wallet.address.toString(), + height: currentHeight, + }, + }, }, }, - }, - }, - ), - ).toBe(vestingAmount.toString()); - expect( - await neutronChain.queryContract( - contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], - { - historical_extension: { - msg: { - unclaimed_total_amount_at_height: { - height: currentHeight, + ), + ).toBe(vestingAmount.toString()); + expect( + await neutronChain.queryContract( + contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], + { + historical_extension: { + msg: { + unclaimed_amount_at_height: { + address: cmUser2.wallet.address.toString(), + height: currentHeight, + }, + }, }, }, - }, - }, - ), - ).toBe(vestingAmount.toString()); + ), + ).toBe(vestingAmount.toString()); + expect( + await neutronChain.queryContract( + contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], + { + historical_extension: { + msg: { + unclaimed_total_amount_at_height: { + height: currentHeight, + }, + }, + }, + }, + ), + ).toBe((2 * vestingAmount).toString()); + }); + + test('record voting power after vesting account addition', async () => { + heightAfterAdd = await env.getHeight(neutronChain.sdk); + user1VpAfterAdd = await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightAfterAdd, + ); + user2VpAfterAdd = await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightAfterAdd, + ); + totalVpAfterAdd = await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightAfterAdd, + ); + }); + test('check voting power change', async () => { + expect(+user1VpAfterAdd.power).toEqual( + +user1VpBeforeAdd.power + vestingAmount, + ); + expect(+user2VpAfterAdd.power).toEqual( + +user2VpBeforeAdd.power + vestingAmount, + ); + expect(+totalVpAfterAdd.power).toEqual( + +totalVpBeforeAdd.power + 2 * vestingAmount, + ); + }); + }); + + describe('check historical voting power', () => { + test('compare to initial voting power', async () => { + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightInit, + ), + ).toEqual(user1VpInit); + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightInit, + ), + ).toEqual(user2VpInit); + expect( + await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightInit, + ), + ).toEqual(totalVpInit); + }); + + test('compare to voting power before vesting account addition', async () => { + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightBeforeAdd, + ), + ).toEqual(user1VpBeforeAdd); + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightBeforeAdd, + ), + ).toEqual(user2VpBeforeAdd); + expect( + await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightBeforeAdd, + ), + ).toEqual(totalVpBeforeAdd); + }); + }); }); - describe('remove vesting account', () => { + describe('remove vesting accounts', () => { let clawbackAccount: string; let clawbackAccountBalance: number; - test('not allowed to a stranger', async () => { - clawbackAccount = cmManager.wallet.address.toString(); - clawbackAccountBalance = await neutronChain.queryDenomBalance( - clawbackAccount, - NEUTRON_DENOM, + // vars for state before voting accounts removed + let user1VpBeforeRm: VotingPowerResponse; + let user2VpBeforeRm: VotingPowerResponse; + let totalVpBeforeRm: VotingPowerResponse; + let heightBeforeRm: number; + // vars for state after voting accounts removed + let user1VpAfterRm: VotingPowerResponse; + let user2VpAfterRm: VotingPowerResponse; + let totalVpAfterRm: VotingPowerResponse; + let heightAfterRm: number; + test('record current voting power', async () => { + heightBeforeRm = await env.getHeight(neutronChain.sdk); + user1VpBeforeRm = await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightBeforeRm, ); - await expect( - cmUser2.executeContract( + user2VpBeforeRm = await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightBeforeRm, + ); + totalVpBeforeRm = await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightBeforeRm, + ); + }); + + describe('remove vesting accounts', () => { + test('execute remove_vesting_accounts', async () => { + clawbackAccount = cmManager.wallet.address.toString(); + clawbackAccountBalance = await neutronChain.queryDenomBalance( + clawbackAccount, + NEUTRON_DENOM, + ); + await cmInstantiator.executeContract( contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], JSON.stringify({ managed_extension: { @@ -413,69 +588,162 @@ describe('Neutron / TGE / Investors vesting vault', () => { }, }, }), - [{ denom: NEUTRON_DENOM, amount: vestingAmount.toString() }], - ), - ).rejects.toThrow(/Unauthorized/); - }); - test('successful as the owner', async () => { - const execRes = await cmInstantiator.executeContract( - contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], - JSON.stringify({ - managed_extension: { - msg: { - remove_vesting_accounts: { - vesting_accounts: [cmUser1.wallet.address.toString()], - clawback_account: clawbackAccount, - }, - }, - }, - }), - [{ denom: NEUTRON_DENOM, amount: vestingAmount.toString() }], - ); - expect(execRes.code).toBe(0); - }); - test('unclaimed amount after removal', async () => { - await neutronChain.blockWaiter.waitBlocks(1); - const currentHeight = await env.getHeight(neutronChain.sdk); - expect( - await neutronChain.queryContract( - contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], - { - historical_extension: { - msg: { - unclaimed_amount_at_height: { - address: cmUser1.wallet.address.toString(), - height: currentHeight, + ); + }); + + test('unclaimed amount after removal', async () => { + await neutronChain.blockWaiter.waitBlocks(1); + const currentHeight = await env.getHeight(neutronChain.sdk); + expect( + await neutronChain.queryContract( + contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], + { + historical_extension: { + msg: { + unclaimed_amount_at_height: { + address: cmUser1.wallet.address.toString(), + height: currentHeight, + }, }, }, }, - }, - ), - ).toBe('0'); - expect( - await neutronChain.queryContract( - contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], - { - historical_extension: { - msg: { - unclaimed_total_amount_at_height: { - height: currentHeight, + ), + ).toBe('0'); + expect( + await neutronChain.queryContract( + contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], + { + historical_extension: { + msg: { + unclaimed_total_amount_at_height: { + height: currentHeight, + }, }, }, }, - }, - ), - ).toBe('0'); - }); - test('clawback account topped up', async () => { - const clawbackAccountBalanceAfterRemoval = - await neutronChain.queryDenomBalance( - clawbackAccount, - NEUTRON_DENOM, + ), + ).toBe(vestingAmount.toString()); // only user2's part left + }); + + test('record voting power after vesting account removal', async () => { + heightAfterRm = await env.getHeight(neutronChain.sdk); + user1VpAfterRm = await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightAfterRm, ); - expect(clawbackAccountBalanceAfterRemoval).toBe( - clawbackAccountBalance + vestingAmount, - ); + user2VpAfterRm = await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightAfterRm, + ); + totalVpAfterRm = await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightAfterRm, + ); + }); + + test('check voting power change', async () => { + expect(+user1VpAfterRm.power).toEqual(0); + expect(+user2VpAfterRm.power).toEqual( + +user2VpBeforeRm.power, // wasn't changed + ); + expect(+totalVpAfterRm.power).toEqual( + +user2VpBeforeRm.power, // only user2's part left + ); + }); + + test('clawback account topped up', async () => { + const clawbackAccountBalanceAfterRemoval = + await neutronChain.queryDenomBalance( + clawbackAccount, + NEUTRON_DENOM, + ); + expect(clawbackAccountBalanceAfterRemoval).toBe( + clawbackAccountBalance + vestingAmount, + ); + }); + }); + + describe('check historical voting power', () => { + test('compare to initial voting power', async () => { + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightInit, + ), + ).toEqual(user1VpInit); + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightInit, + ), + ).toEqual(user2VpInit); + expect( + await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightInit, + ), + ).toEqual(totalVpInit); + }); + test('compare to voting power before vesting account addition', async () => { + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightBeforeAdd, + ), + ).toEqual(user1VpBeforeAdd); + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightBeforeAdd, + ), + ).toEqual(user2VpBeforeAdd); + expect( + await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightBeforeAdd, + ), + ).toEqual(totalVpBeforeAdd); + }); + test('compare to voting power before vesting account removal', async () => { + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser1.wallet.address.toString(), + heightBeforeRm, + ), + ).toEqual(user1VpBeforeRm); + expect( + await votingPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + cmUser2.wallet.address.toString(), + heightBeforeRm, + ), + ).toEqual(user2VpBeforeRm); + expect( + await totalPowerAtHeight( + neutronChain, + contractAddresses[INVESTORS_VESTING_VAULT_CONTRACT_KEY], + heightBeforeRm, + ), + ).toEqual(totalVpBeforeRm); + }); }); }); }); @@ -515,6 +783,26 @@ describe('Neutron / TGE / Investors vesting vault', () => { ).rejects.toThrow(/Unauthorized/); }); + describe('remove vesting accounts is permissioned', () => { + test('removal not allowed to a stranger', async () => { + await expect( + cmUser2.executeContract( + contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], + JSON.stringify({ + managed_extension: { + msg: { + remove_vesting_accounts: { + vesting_accounts: [cmUser1.wallet.address.toString()], + clawback_account: cmUser2.wallet.address.toString(), + }, + }, + }, + }), + ), + ).rejects.toThrow(/Unauthorized/); + }); + }); + describe('register vesting accounts is permissioned', () => { test('via send cw20 by a stranger', async () => { // create a random cw20 token with allocation to user1 @@ -644,7 +932,7 @@ const setInvestorsVestingAsset = async ( instantiator: cosmosWrapper.WalletWrapper, contractAddresses: Record, ) => { - const execRes = await instantiator.executeContract( + await instantiator.executeContract( contractAddresses[INVESTORS_VESTING_CONTRACT_KEY], JSON.stringify({ set_vesting_token: { @@ -656,7 +944,6 @@ const setInvestorsVestingAsset = async ( }, }), ); - expect(execRes.code).toBe(0); }; const deployInvestorsVestingVaultContract = async ( @@ -695,3 +982,31 @@ type VotingPowerResponse = { power: string; height: number; }; + +const totalPowerAtHeight = async ( + chain: cosmosWrapper.CosmosWrapper, + contract: string, + height?: number, +): Promise => + chain.queryContract(contract, { + total_power_at_height: + typeof height === 'undefined' ? {} : { height: height }, + }); + +const votingPowerAtHeight = async ( + chain: cosmosWrapper.CosmosWrapper, + contract: string, + address: string, + height?: number, +): Promise => + chain.queryContract(contract, { + voting_power_at_height: + typeof height === 'undefined' + ? { + address: address, + } + : { + address: address, + height: height, + }, + });