Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added tests for update_reserve and unauthorized withdraw_all #NTRN-95 #192

Merged
merged 3 commits into from
Aug 22, 2023
Merged
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
Binary file not shown.
27 changes: 27 additions & 0 deletions src/helpers/cosmos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,33 @@ export class WalletWrapper {
]);
}

async migrateContract(
contract: string,
codeId: number,
msg: string | Record<string, unknown>,
): Promise<InlineResponse20075TxResponse> {
const sender = this.wallet.address.toString();
const msgMigrate = new cosmwasmproto.cosmwasm.wasm.v1.MsgMigrateContract({
sender,
contract,
code_id: codeId + '',
msg: Buffer.from(typeof msg === 'string' ? msg : JSON.stringify(msg)),
});
const res = await this.execTx(
{
gas_limit: Long.fromString('5000000'),
amount: [{ denom: this.chain.denom, amount: '20000' }],
},
[msgMigrate],
);
if (res.tx_response.code !== 0) {
throw new Error(
`${res.tx_response.raw_log}\nFailed tx hash: ${res.tx_response.txhash}`,
);
}
return res?.tx_response;
}

async executeContract(
contract: string,
msg: string,
Expand Down
157 changes: 152 additions & 5 deletions src/testcases/run_in_band/tge.airdrop.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('Neutron / TGE / Airdrop', () => {
let neutronChain: CosmosWrapper;
let neutronAccount1: WalletWrapper;
let neutronAccount2: WalletWrapper;
let neutronAccount3: WalletWrapper;
const codeIds: Record<string, CodeId> = {};
const contractAddresses: Record<string, string> = {};
let airdrop: InstanceType<typeof Airdrop>;
Expand All @@ -45,6 +46,10 @@ describe('Neutron / TGE / Airdrop', () => {
neutronChain,
testState.wallets.qaNeutronThree.genQaWal1,
);
neutronAccount3 = new WalletWrapper(
neutronChain,
testState.wallets.qaNeutronFour.genQaWal1,
);
const accounts = [
{
address: testState.wallets.neutron.demo1.address.toString(),
Expand Down Expand Up @@ -75,6 +80,15 @@ describe('Neutron / TGE / Airdrop', () => {
expect(codeId).toBeGreaterThan(0);
codeIds[contract] = codeId;
}
// wasmcode to test migration airdrop contract from the mainnet codeId 22 to a new wasm code
// $ sha256sum contracts_thirdparty/cw20_merkle_airdrop_orig.wasm
// b6595694b8cf752a085b34584ae37bf59e2236d916a1fd01dd014af8967204aa contracts_thirdparty/cw20_merkle_airdrop_orig.wasm
// https://neutron.celat.one/neutron-1/codes/22
const codeId = await neutronAccount1.storeWasm(
'../contracts_thirdparty/cw20_merkle_airdrop_orig.wasm',
);
expect(codeId).toBeGreaterThan(0);
codeIds['TGE_AIRDROP_ORIG'] = codeId;
});
it('should instantiate credits contract', async () => {
const res = await neutronAccount1.instantiateContract(
Expand Down Expand Up @@ -102,7 +116,7 @@ describe('Neutron / TGE / Airdrop', () => {
hrp: 'neutron',
};
const res = await neutronAccount1.instantiateContract(
codeIds['TGE_AIRDROP'],
codeIds['TGE_AIRDROP_ORIG'],
JSON.stringify(initParams),
'airdrop',
);
Expand Down Expand Up @@ -135,6 +149,30 @@ describe('Neutron / TGE / Airdrop', () => {
);
expect(res.code).toEqual(0);
});

it('should not update reserve address by owner', async () => {
await expect(
neutronAccount1.executeContract(
contractAddresses['TGE_AIRDROP'],
JSON.stringify({
update_reserve: {
address: neutronAccount3.wallet.address.toString(),
},
}),
),
).rejects.toThrow(
/unknown variant `update_reserve`, expected one of `claim`, `withdraw_all`, `pause`, `resume`/,
);
expect(
await neutronChain.queryContract(contractAddresses.TGE_AIRDROP, {
config: {},
}),
).toMatchObject({
owner: neutronAccount1.wallet.address.toString(),
credits_address: contractAddresses.TGE_CREDITS,
reserve_address: reserveAddress,
});
});
});

describe('Airdrop', () => {
Expand Down Expand Up @@ -269,6 +307,102 @@ describe('Neutron / TGE / Airdrop', () => {
);
expect(res.code).toEqual(0);
});

it('should migrate in the middle of TGE', async () => {
const res = await neutronAccount1.migrateContract(
contractAddresses['TGE_AIRDROP'],
codeIds['TGE_AIRDROP'],
{},
);
expect(res.code).toEqual(0);
});

it('should not update reserve address by random account', async () => {
await expect(
neutronAccount3.executeContract(
contractAddresses['TGE_AIRDROP'],
JSON.stringify({
update_reserve: {
address: neutronAccount3.wallet.address.toString(),
},
}),
),
).rejects.toThrow(/Unauthorized/);
expect(
await neutronChain.queryContract(contractAddresses.TGE_AIRDROP, {
config: {},
}),
).toMatchObject({
owner: neutronAccount1.wallet.address.toString(),
credits_address: contractAddresses.TGE_CREDITS,
reserve_address: reserveAddress,
});
});

it('should update reserve address by owner account', async () => {
const res = await neutronAccount1.executeContract(
contractAddresses['TGE_AIRDROP'],
JSON.stringify({
update_reserve: {
address: neutronAccount3.wallet.address.toString(),
},
}),
);
expect(res.code).toEqual(0);
expect(
await neutronChain.queryContract(contractAddresses.TGE_AIRDROP, {
config: {},
}),
).toMatchObject({
owner: neutronAccount1.wallet.address.toString(),
credits_address: contractAddresses.TGE_CREDITS,
reserve_address: neutronAccount3.wallet.address.toString(),
});
});

it('should not update reserve address by old reserve', async () => {
await expect(
neutronAccount2.executeContract(
contractAddresses['TGE_AIRDROP'],
JSON.stringify({
update_reserve: {
address: neutronAccount2.wallet.address.toString(),
},
}),
),
).rejects.toThrow(/Unauthorized/);
expect(
await neutronChain.queryContract(contractAddresses.TGE_AIRDROP, {
config: {},
}),
).toMatchObject({
owner: neutronAccount1.wallet.address.toString(),
credits_address: contractAddresses.TGE_CREDITS,
reserve_address: neutronAccount3.wallet.address.toString(),
});
});

it('should update reserve address by new reserve', async () => {
const res = await neutronAccount3.executeContract(
contractAddresses['TGE_AIRDROP'],
JSON.stringify({
update_reserve: {
address: neutronAccount2.wallet.address.toString(),
},
}),
);
expect(res.code).toEqual(0);
expect(
await neutronChain.queryContract(contractAddresses.TGE_AIRDROP, {
config: {},
}),
).toMatchObject({
owner: neutronAccount1.wallet.address.toString(),
credits_address: contractAddresses.TGE_CREDITS,
reserve_address: reserveAddress,
});
});

it('should return is claimed true', async () => {
const res = await neutronChain.queryContract<{ is_claimed: boolean }>(
contractAddresses['TGE_AIRDROP'],
Expand Down Expand Up @@ -392,7 +526,7 @@ describe('Neutron / TGE / Airdrop', () => {
});
it('should not be able to withdraw all before end', async () => {
await expect(
neutronAccount1.executeContract(
neutronAccount2.executeContract(
contractAddresses['TGE_AIRDROP'],
JSON.stringify({
withdraw_all: {},
Expand All @@ -403,8 +537,20 @@ describe('Neutron / TGE / Airdrop', () => {
/withdraw_all is unavailable, it will become available at/,
);
});
it('should be able to withdraw all', async () => {
it('should not be able to withdraw all by non reserve address', async () => {
await waitTill(times.airdropVestingStart + times.vestingDuration + 5);
await expect(
neutronAccount1.executeContract(
contractAddresses['TGE_AIRDROP'],
JSON.stringify({
withdraw_all: {},
}),
[],
),
).rejects.toThrow(/Unauthorized/);
});

it('should be able to withdraw all by reserve address', async () => {
const availableBalanceCNTRN = await neutronChain.queryContract<{
balance: string;
}>(contractAddresses['TGE_CREDITS'], {
Expand All @@ -415,7 +561,7 @@ describe('Neutron / TGE / Airdrop', () => {
const reserveBalanceNTRN = (
await neutronChain.queryBalances(reserveAddress)
).balances.find((b) => b.denom === NEUTRON_DENOM)?.amount;
const res = await neutronAccount1.executeContract(
const res = await neutronAccount2.executeContract(
contractAddresses['TGE_AIRDROP'],
JSON.stringify({
withdraw_all: {},
Expand All @@ -437,7 +583,8 @@ describe('Neutron / TGE / Airdrop', () => {
expect(availableBalanceCNTRNAfter.balance).toEqual('0');
expect(
parseInt(reserveBalanceNTRNAfter || '0') -
parseInt(reserveBalanceNTRN || '0'),
parseInt(reserveBalanceNTRN || '0') +
10000, // fee compensation for execution withdraw all
).toEqual(parseInt(availableBalanceCNTRN.balance));
});
});
Expand Down