From 28fe493c0179894066d6251f471f285d85c972fc Mon Sep 17 00:00:00 2001 From: Andrei Zavgorodnii Date: Mon, 11 Nov 2024 15:36:44 +0000 Subject: [PATCH] upgrading --- package.json | 2 +- src/testcases/run_in_band/flashloans.test.ts | 420 +++++++++---------- 2 files changed, 204 insertions(+), 218 deletions(-) diff --git a/package.json b/package.json index 6bdb1954..127c3dc9 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "test:float": "NO_WAIT_CHANNEL1=1 NO_WAIT_HTTP2=1 NO_WAIT_CHANNEL2=1 NO_WAIT_DELAY=1 vitest --run src/testcases/run_in_band/float --bail 1", "test:dex_grpc": "NO_WAIT_CHANNEL1=1 NO_WAIT_HTTP2=1 NO_WAIT_CHANNEL2=1 NO_WAIT_DELAY=1 vitest --run src/testcases/run_in_band/dex_grpc --bail 1", "test:chain_manager": "vitest --run src/testcases/run_in_band/chain_manager --bail 1", - "test:flashloans": "jest -b src/testcases/run_in_band/flashloans", + "test:flashloans": "vitest --run src/testcases/run_in_band/flashloans --bail 1", "test:feemarket": "NO_WAIT_CHANNEL1=1 NO_WAIT_HTTP2=1 NO_WAIT_CHANNEL2=1 NO_WAIT_DELAY=1 vitest --run src/testcases/run_in_band/feemarket --bail 1", "test:ibc_rate_limit": "vitest --run src/testcases/run_in_band/ibc_rate_limit --bail 1", "lint": "eslint ./src", diff --git a/src/testcases/run_in_band/flashloans.test.ts b/src/testcases/run_in_band/flashloans.test.ts index abcde734..ed78f76c 100644 --- a/src/testcases/run_in_band/flashloans.test.ts +++ b/src/testcases/run_in_band/flashloans.test.ts @@ -1,115 +1,115 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import '@neutron-org/neutronjsplus'; -import { - WalletWrapper, - CosmosWrapper, - NEUTRON_DENOM, -} from '@neutron-org/neutronjsplus/dist/cosmos'; -import { TestStateLocalCosmosTestNet } from '@neutron-org/neutronjsplus'; +import { LocalState } from '../../helpers/local_state'; import { Dao, DaoMember, getDaoContracts, + getNeutronDAOCore, } from '@neutron-org/neutronjsplus/dist/dao'; -import { Wallet } from '@neutron-org/neutronjsplus/dist/types'; - +import { NEUTRON_DENOM } from '@neutron-org/neutronjsplus/dist/constants'; import config from '../../config.json'; -import { MsgGrant } from 'cosmjs-types/cosmos/authz/v1beta1/tx'; import { GenericAuthorization } from 'cosmjs-types/cosmos/authz/v1beta1/authz'; -import Long from 'long'; -import cosmosclient from '@cosmos-client/core'; +import { SigningNeutronClient } from '../../helpers/signing_neutron_client'; +import { inject, RunnerTestSuite } from 'vitest'; +import { Wallet } from '../../helpers/wallet'; +import { ProtobufRpcClient } from '@cosmjs/stargate'; + +import { MsgGrant } from '@neutron-org/neutronjs/cosmos/authz/v1beta1/tx'; +import { base64FromBytes } from '@neutron-org/neutronjs/helpers'; const DAO_INITIAL_BALANCE = 1000; // untrn describe('Neutron / Flashloans', () => { - let testState: TestStateLocalCosmosTestNet; - let neutronChain: CosmosWrapper; - let neutronAccount1: WalletWrapper; + let testState: LocalState; + let neutronClient: SigningNeutronClient; + let neutronRpcClient: ProtobufRpcClient; + let neutronWallet: Wallet; let mainDaoMember: DaoMember; - let demo1Wallet: Wallet; let mainDao: Dao; let neutronFlashloansAddress: string; let neutronFlashloansUserAddress: string; - beforeAll(async () => { - testState = new TestStateLocalCosmosTestNet(config); - await testState.init(); - demo1Wallet = testState.wallets.qaNeutron.genQaWal1; - neutronChain = new CosmosWrapper( - testState.sdk1, - testState.blockWaiter1, - NEUTRON_DENOM, + beforeAll(async (suite: RunnerTestSuite) => { + testState = await LocalState.create(config, inject('mnemonics'), suite); + neutronRpcClient = await testState.neutronRpcClient(); + neutronWallet = await testState.nextWallet('neutron'); + neutronClient = await SigningNeutronClient.connectWithSigner( + testState.rpcNeutron, + neutronWallet.directwallet, + neutronWallet.address, ); - neutronAccount1 = new WalletWrapper(neutronChain, demo1Wallet); // ---------------------SET UP THE DAO - const daoCoreAddress = await neutronChain.getNeutronDAOCore(); - const daoContracts = await getDaoContracts(neutronChain, daoCoreAddress); + const daoCoreAddress = await getNeutronDAOCore( + neutronClient, + neutronRpcClient, + ); + const daoContracts = await getDaoContracts(neutronClient, daoCoreAddress); - mainDao = new Dao(neutronChain, daoContracts); - mainDaoMember = new DaoMember(neutronAccount1, mainDao); + mainDao = new Dao(neutronClient, daoContracts); + mainDaoMember = new DaoMember( + mainDao, + neutronClient.client, + neutronWallet.address, + NEUTRON_DENOM, + ); await mainDaoMember.bondFunds('10000'); - await neutronAccount1.msgSend(daoCoreAddress, { - denom: 'untrn', - amount: DAO_INITIAL_BALANCE.toString(), - }); + await neutronClient.sendTokens( + daoCoreAddress, + [{ denom: NEUTRON_DENOM, amount: DAO_INITIAL_BALANCE.toString() }], + { + gas: '200000', + amount: [{ denom: NEUTRON_DENOM, amount: '1000' }], + }, + ); // ----------------------INSTANTIATE FLASHLOANS - const neutronFlashloansCodeId = await neutronAccount1.storeWasm( + const neutronFlashloansCodeId = await neutronClient.upload( 'neutron_flashloans.wasm', ); const neutronFlashloansInitMsg = { - owner: demo1Wallet.address, + owner: neutronWallet.address, source: daoCoreAddress, fee_rate: '0.01', }; - const neutronFlashloansCodeIdRes = - await neutronAccount1.instantiateContract( - neutronFlashloansCodeId, - JSON.stringify(neutronFlashloansInitMsg), - 'neutron.flashloans', - ); - const f = (arr: Record[], id: number) => - (arr.find((v) => Number(v.code_id) == id) || {})._contract_address; - neutronFlashloansAddress = f( - neutronFlashloansCodeIdRes, + neutronFlashloansAddress = await neutronClient.instantiate( neutronFlashloansCodeId, + neutronFlashloansInitMsg, ); // -----------------INSTANTIATE FLASHLOANS USER CONTRACT - const neutronFlashloansUserCodeId = await neutronAccount1.storeWasm( + const neutronFlashloansUserCodeId = await neutronClient.upload( 'neutron_flashloans_user.wasm', ); const neutronFlashloansUserInitMsg = {}; - const neutronFlashloansUserCodeIdRes = - await neutronAccount1.instantiateContract( - neutronFlashloansUserCodeId, - JSON.stringify(neutronFlashloansUserInitMsg), - 'neutron.flashloans', - ); - neutronFlashloansUserAddress = f( - neutronFlashloansUserCodeIdRes, + neutronFlashloansUserAddress = await neutronClient.instantiate( neutronFlashloansUserCodeId, + neutronFlashloansUserInitMsg, ); - await neutronAccount1.msgSend(neutronFlashloansUserAddress, { - denom: 'untrn', - amount: '50', - }); + await neutronClient.sendTokens( + neutronFlashloansUserAddress, + [{ denom: 'untrn', amount: '50' }], + { + gas: '200000', + amount: [{ denom: NEUTRON_DENOM, amount: '1000' }], + }, + ); }); describe('Grant a GenericAuthorization from the DAO to the flashloans contract', () => { let proposalId: number; test('Create and submit proposal', async () => { - const daoCoreAddress = await neutronChain.getNeutronDAOCore(); - - const expiration = new Date(); - expiration.setDate(expiration.getDate() + 1); + const daoCoreAddress = await getNeutronDAOCore( + neutronClient, + neutronRpcClient, + ); const genericAuthorization = GenericAuthorization.fromPartial({ msg: '/cosmos.bank.v1beta1.MsgSend', @@ -123,18 +123,14 @@ describe('Neutron / Flashloans', () => { typeUrl: '/cosmos.authz.v1beta1.GenericAuthorization', value: GenericAuthorization.encode(genericAuthorization).finish(), }, - expiration: { - seconds: Long.fromNumber(expiration.getTime() / 1000), - nanos: 0, - }, }, }); const stargateMsg = { - stargate: new cosmosclient.proto.google.protobuf.Any({ - type_url: '/cosmos.authz.v1beta1.MsgGrant', - value: MsgGrant.encode(msgGrant).finish(), - }), + stargate: { + type_url: MsgGrant.typeUrl, + value: base64FromBytes(MsgGrant.encode(msgGrant).finish()), + }, }; proposalId = await mainDaoMember.submitSingleChoiceProposal( @@ -160,50 +156,46 @@ describe('Neutron / Flashloans', () => { describe('Test different ways to request a loan', () => { test('Request a flashloan (and return it)', async () => { - const res = await neutronAccount1.executeContract( - neutronFlashloansUserAddress, - JSON.stringify({ - request_loan: { - flashloans_contract: neutronFlashloansAddress, - execution_mode: 0, // MODE_RETURN_LOAN - amount: [ - { - denom: 'untrn', - amount: '100', - }, - ], - }, - }), - ); + const res = await neutronClient.execute(neutronFlashloansUserAddress, { + request_loan: { + flashloans_contract: neutronFlashloansAddress, + execution_mode: 0, // MODE_RETURN_LOAN + amount: [ + { + denom: 'untrn', + amount: '100', + }, + ], + }, + }); expect(res.code).toEqual(0); // We started with 1000untrn on the dao balance, requested 100 with a // 0.01 fee, and expect to see DAO_INITIAL_BALANCE + 1 after the loan // is paid back expect( - await neutronChain.queryDenomBalance( - mainDao.contracts.core.address, - 'untrn', - ), - ).toEqual(DAO_INITIAL_BALANCE + 1); + ( + await neutronClient.getBalance( + mainDao.contracts.core.address, + NEUTRON_DENOM, + ) + ).amount, + ).toEqual((DAO_INITIAL_BALANCE + 1).toString()); }); test('Request a flashloan (and not return it)', async () => { try { - const res = await neutronAccount1.executeContract( - neutronFlashloansUserAddress, - JSON.stringify({ - request_loan: { - flashloans_contract: neutronFlashloansAddress, - execution_mode: 1, // MODE_WITHHOLD_LOAN - amount: [ - { - denom: 'untrn', - amount: '100', - }, - ], - }, - }), - ); + const res = await neutronClient.execute(neutronFlashloansUserAddress, { + request_loan: { + flashloans_contract: neutronFlashloansAddress, + execution_mode: 1, // MODE_WITHHOLD_LOAN + amount: [ + { + denom: 'untrn', + amount: '100', + }, + ], + }, + }); expect(res.code).toEqual(1); } catch (error) { expect(error.message).toContain( @@ -212,59 +204,57 @@ describe('Neutron / Flashloans', () => { // Execution failed, the DAO balance should stay the same. expect( - await neutronChain.queryDenomBalance( - mainDao.contracts.core.address, - 'untrn', - ), - ).toEqual(DAO_INITIAL_BALANCE + 1); + ( + await neutronClient.getBalance( + mainDao.contracts.core.address, + NEUTRON_DENOM, + ) + ).amount, + ).toEqual((DAO_INITIAL_BALANCE + 1).toString()); } }); test('Request a flashloan (request more that is available)', async () => { try { - const res = await neutronAccount1.executeContract( - neutronFlashloansUserAddress, - JSON.stringify({ - request_loan: { - flashloans_contract: neutronFlashloansAddress, - execution_mode: 0, // MODE_RETURN_LOAN - amount: [ - { - denom: 'untrn', - amount: '100000', - }, - ], - }, - }), - ); + const res = await neutronClient.execute(neutronFlashloansUserAddress, { + request_loan: { + flashloans_contract: neutronFlashloansAddress, + execution_mode: 0, // MODE_RETURN_LOAN + amount: [ + { + denom: 'untrn', + amount: '100000', + }, + ], + }, + }); expect(res.code).toEqual(1); } catch (error) { expect(error.message).toContain("Source doesn't have enough untrn"); // Execution failed, the DAO balance should stay the same. expect( - await neutronChain.queryDenomBalance( - mainDao.contracts.core.address, - 'untrn', - ), - ).toEqual(DAO_INITIAL_BALANCE + 1); + ( + await neutronClient.getBalance( + mainDao.contracts.core.address, + NEUTRON_DENOM, + ) + ).amount, + ).toEqual((DAO_INITIAL_BALANCE + 1).toString()); } }); test('Request a flashloan (and return more than required)', async () => { try { - const res = await neutronAccount1.executeContract( - neutronFlashloansUserAddress, - JSON.stringify({ - request_loan: { - flashloans_contract: neutronFlashloansAddress, - execution_mode: 1, // MODE_WITHHOLD_LOAN - amount: [ - { - denom: 'untrn', - amount: '100', - }, - ], - }, - }), - ); + const res = await neutronClient.execute(neutronFlashloansUserAddress, { + request_loan: { + flashloans_contract: neutronFlashloansAddress, + execution_mode: 1, // MODE_WITHHOLD_LOAN + amount: [ + { + denom: 'untrn', + amount: '100', + }, + ], + }, + }); expect(res.code).toEqual(1); } catch (error) { expect(error.message).toContain( @@ -272,30 +262,29 @@ describe('Neutron / Flashloans', () => { ); // Execution failed, the DAO balance should stay the same. expect( - await neutronChain.queryDenomBalance( - mainDao.contracts.core.address, - 'untrn', - ), - ).toEqual(DAO_INITIAL_BALANCE + 1); + ( + await neutronClient.getBalance( + mainDao.contracts.core.address, + NEUTRON_DENOM, + ) + ).amount, + ).toEqual((DAO_INITIAL_BALANCE + 1).toString()); } }); test('Request a flashloan (and request another one recursively)', async () => { try { - const res = await neutronAccount1.executeContract( - neutronFlashloansUserAddress, - JSON.stringify({ - request_loan: { - flashloans_contract: neutronFlashloansAddress, - execution_mode: 3, // MODE_WITHHOLD_LOAN - amount: [ - { - denom: 'untrn', - amount: '100', - }, - ], - }, - }), - ); + const res = await neutronClient.execute(neutronFlashloansUserAddress, { + request_loan: { + flashloans_contract: neutronFlashloansAddress, + execution_mode: 3, // MODE_WITHHOLD_LOAN + amount: [ + { + denom: 'untrn', + amount: '100', + }, + ], + }, + }); expect(res.code).toEqual(1); } catch (error) { expect(error.message).toContain( @@ -303,76 +292,73 @@ describe('Neutron / Flashloans', () => { ); // Execution failed, the DAO balance should stay the same. expect( - await neutronChain.queryDenomBalance( - mainDao.contracts.core.address, - 'untrn', - ), - ).toEqual(DAO_INITIAL_BALANCE + 1); + ( + await neutronClient.getBalance( + mainDao.contracts.core.address, + NEUTRON_DENOM, + ) + ).amount, + ).toEqual((DAO_INITIAL_BALANCE + 1).toString()); } }); test('Request a flashloan (and fail internally)', async () => { try { - const res = await neutronAccount1.executeContract( - neutronFlashloansUserAddress, - JSON.stringify({ - request_loan: { - flashloans_contract: neutronFlashloansAddress, - execution_mode: 42, // Not 0, 1, 2, or 3, makes the flashloans user contract fail - amount: [ - { - denom: 'untrn', - amount: '100', - }, - ], - }, - }), - ); + const res = await neutronClient.execute(neutronFlashloansUserAddress, { + request_loan: { + flashloans_contract: neutronFlashloansAddress, + execution_mode: 42, // Not 0, 1, 2, or 3, makes the flashloans user contract fail + amount: [ + { + denom: 'untrn', + amount: '100', + }, + ], + }, + }); expect(res.code).toEqual(1); } catch (error) { expect(error.message).toContain('The ProcessLoan handler failed'); // Execution failed, the DAO balance should stay the same. expect( - await neutronChain.queryDenomBalance( - mainDao.contracts.core.address, - 'untrn', - ), - ).toEqual(DAO_INITIAL_BALANCE + 1); + ( + await neutronClient.getBalance( + mainDao.contracts.core.address, + NEUTRON_DENOM, + ) + ).amount, + ).toEqual((DAO_INITIAL_BALANCE + 1).toString()); } }); test('Change fee to 0.0 and request a flashloan', async () => { - let res = await neutronAccount1.executeContract( - neutronFlashloansAddress, - JSON.stringify({ - update_config: { - fee_rate: '0.0', - }, - }), - ); + let res = await neutronClient.execute(neutronFlashloansAddress, { + update_config: { + fee_rate: '0.0', + }, + }); expect(res.code).toEqual(0); - res = await neutronAccount1.executeContract( - neutronFlashloansUserAddress, - JSON.stringify({ - request_loan: { - flashloans_contract: neutronFlashloansAddress, - execution_mode: 0, // MODE_RETURN_LOAN - amount: [ - { - denom: 'untrn', - amount: '100', - }, - ], - }, - }), - ); + res = await neutronClient.execute(neutronFlashloansUserAddress, { + request_loan: { + flashloans_contract: neutronFlashloansAddress, + execution_mode: 0, // MODE_RETURN_LOAN + amount: [ + { + denom: 'untrn', + amount: '100', + }, + ], + }, + }); expect(res.code).toEqual(0); // The fee is 0.0, so the DAO balance should stay the same. expect( - await neutronChain.queryDenomBalance( - mainDao.contracts.core.address, - 'untrn', - ), - ).toEqual(DAO_INITIAL_BALANCE + 1); + ( + await neutronClient.getBalance( + mainDao.contracts.core.address, + NEUTRON_DENOM, + ) + ).amount, + ).toEqual((DAO_INITIAL_BALANCE + 1).toString()); }); }); });