Skip to content

Commit

Permalink
Merge pull request #192 from neutron-org/feat/airdrop-update-reserve
Browse files Browse the repository at this point in the history
feat: added tests for update_reserve and unauthorized withdraw_all #NTRN-95
  • Loading branch information
pr0n00gler authored Aug 22, 2023
2 parents c0a284d + a729d33 commit faf596b
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 5 deletions.
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

0 comments on commit faf596b

Please sign in to comment.