This commit is contained in:
fiftyeightandeight
2024-03-24 10:14:11 +08:00
parent 492e034b8c
commit d3028d3b96
17 changed files with 218 additions and 722 deletions

View File

@@ -9,6 +9,7 @@ export const createClientMockSetup = () => {
const bot = accounts.get('wallet_3')!;
const manager = accounts.get('wallet_4')!;
const operator3 = accounts.get('wallet_5')!;
const user2 = accounts.get('wallet_6')!;
const contracts = {
endpoint: 'lqstx-mint-endpoint-v1-02',
@@ -17,14 +18,12 @@ export const createClientMockSetup = () => {
lqstx: 'token-lqstx',
vlqstx: 'token-vlqstx',
wstx: 'token-wstx',
strategy: 'mock-strategy',
rebase: 'lisa-rebase-v1-02',
rebase1: 'rebase-mock',
strategy: 'public-pools-strategy',
amm: 'amm-swap-pool-v1-1',
wlqstx: 'token-wlqstx',
dao: 'lisa-dao',
boot: 'regtest-boot',
manager: 'mock-strategy-manager',
boot: 'simnet-boot',
manager: 'public-pools-strategy-manager',
operators: 'operators',
proposal: 'mock-proposal',
proposal2: 'mock-proposal',
@@ -46,13 +45,13 @@ export const createClientMockSetup = () => {
simnet.callPublicFn(contracts.endpoint, 'request-mint', [Cl.uint(amount)], user);
const requestBurn = (amount: IntegerType) =>
simnet.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(amount)], user);
const createPayload = (amount: IntegerType) =>
(
simnet.callReadOnlyFn(contracts.strategy, 'create-payload', [Cl.uint(amount)], manager)
.result as BufferCV
).buffer;
simnet.callPublicFn(contracts.endpoint, 'request-burn', [Cl.uint(amount)], user);
const fundStrategy = (amount: IntegerType) =>
simnet.callPublicFn(contracts.manager, 'fund-strategy', [Cl.list([Cl.uint(amount)])], manager);
const finalizeMint = (requestId: IntegerType) =>
simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(requestId)], bot);
const getRewardCycle = () => {
return (
@@ -97,6 +96,13 @@ export const createClientMockSetup = () => {
);
};
const goToNextRequestCycle = () => {
const cycle = getRequestCycle();
const blocksToMine = getBlocksToStartOfCycle(cycle + 1n);
simnet.mineEmptyBlocks(blocksToMine);
};
const goToNextCycle = () => {
const cycle = getRewardCycle();
const blocksToMine = getBlocksToStartOfCycle(cycle + 1n);
@@ -115,14 +121,17 @@ export const createClientMockSetup = () => {
prepareTest,
requestMint,
requestBurn,
createPayload,
fundStrategy,
finalizeMint,
getRewardCycle,
getRequestCycle,
getBlocksToStartOfCycle,
goToNextCycle,
goToNextRequestCycle,
getRequestCutoff,
liSTXBalance,
user,
user2,
oracle,
bot,
manager,

View File

@@ -31,6 +31,7 @@ describe('LiSTX NFT', () => {
it('user can transfer nft before finalize mint', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
let response = requestMint(100e6);
console.log(response.events);
expect(response.result).toBeOk(Cl.uint(1));
// transfer nft to bot
@@ -39,7 +40,7 @@ describe('LiSTX NFT', () => {
// finalize mint
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay);
simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
// check that bot received liquid stx
expect(liSTXBalance(user)).toBeUint(0);
@@ -72,7 +73,7 @@ describe('LiSTX NFT', () => {
expect(response.result).toBeOk(Cl.uint(1));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay);
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
response = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
expect(response.result).toBeOk(Cl.bool(true));
// request burn

View File

@@ -3,115 +3,37 @@
import { tx } from '@hirosystems/clarinet-sdk';
import { Cl, TupleCV, UIntCV } from '@stacks/transactions';
import { describe, expect, it } from 'vitest';
import { createClientMockSetup } from './clients/mock-client';
const mintDelay = 432;
const accounts = simnet.getAccounts();
const user = accounts.get('wallet_1')!;
const oracle = accounts.get('wallet_2')!;
const bot = accounts.get('wallet_3')!;
const manager = accounts.get('deployer')!;
const operator = accounts.get('wallet_4')!;
const user2 = accounts.get('wallet_5')!;
const contracts = {
endpoint: 'lqstx-mint-endpoint-v1-02',
registry: 'lqstx-mint-registry',
vault: 'lqstx-vault',
lqstx: 'token-lqstx',
vlqstx: 'token-vlqstx',
wstx: 'token-wstx',
strategy: 'public-pools-strategy',
rebase: 'lisa-rebase-v1-02',
rebase1: 'rebase-1-v1-02',
amm: 'amm-swap-pool-v1-1',
wlqstx: 'token-wlqstx',
dao: 'lisa-dao',
boot: 'simnet-boot',
manager: 'public-pools-strategy-manager',
operators: 'operators',
proposal: 'mock-proposal',
burnNft: 'li-stx-burn-nft',
};
const prepareTest = () =>
simnet.mineBlock([
tx.callPublicFn(
contracts.dao,
'construct',
[Cl.contractPrincipal(simnet.deployer, contracts.boot)],
simnet.deployer
),
]);
const getRewardCycle = () => {
return (
simnet.callReadOnlyFn(
contracts.endpoint,
'get-reward-cycle',
[Cl.uint(simnet.blockHeight)],
user
).result as UIntCV
).value;
};
const getBlocksToStartOfCycle = (cycle: bigint) => {
return (
Number(
(
simnet.callReadOnlyFn(
contracts.endpoint,
'get-first-burn-block-in-reward-cycle',
[Cl.uint(cycle)],
user
).result as UIntCV
).value
) - simnet.blockHeight
);
};
const goToNextCycle = () => {
const cycle = getRewardCycle();
const blocksToMine = getBlocksToStartOfCycle(cycle + 1n);
simnet.mineEmptyBlocks(blocksToMine);
};
const { contracts, user, user2, oracle, bot, manager,
prepareTest, goToNextCycle, goToNextRequestCycle,
requestMint, requestBurn, fundStrategy, finalizeMint } = createClientMockSetup();
// 1m STX
const mintAmount = 1_000_000e6;
const requestMint = () =>
simnet.callPublicFn(contracts.endpoint, 'request-mint', [Cl.uint(mintAmount)], user);
// lock mintAmount stx and request burn of 1 stx
const requestBurn = () =>
simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.list([Cl.uint(mintAmount)])], manager),
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(1e6)], user),
]);
const mintDelay = 432;
describe(contracts.endpoint, () => {
it('can request mint', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
const response = requestMint();
const response = requestMint(mintAmount);
expect(response.result).toBeOk(Cl.uint(1));
});
it('can finalize mint', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
goToNextCycle();
const finaliseErr = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
const finaliseErr = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
expect(finaliseErr.result).toBeErr(Cl.uint(7006));
simnet.mineEmptyBlocks(mintDelay + 1); // mint-delay
let responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], user),
]);
expect(responses[0].result).toBeOk(Cl.bool(true));
@@ -121,7 +43,7 @@ describe(contracts.endpoint, () => {
it('can revoke mint', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
let responses = simnet.mineBlock([
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], bot),
@@ -133,7 +55,7 @@ describe(contracts.endpoint, () => {
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay + 1);
responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
]);
expect(responses[0].result).toBeErr(Cl.uint(7007));
});
@@ -141,17 +63,15 @@ describe(contracts.endpoint, () => {
it('can request burn', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
goToNextRequestCycle();
expect(fundStrategy(mintAmount).result).toBeOk(Cl.uint(mintAmount));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay + 1);
const responses = requestBurn();
expect(responses[0].result).toBeOk(Cl.uint(0));
expect(responses[1].result).toBeOk(Cl.bool(true));
expect(responses[2].result).toBeOk(Cl.uint(mintAmount));
expect(responses[3].result).toBeOk(Cl.uint(mintAmount));
expect(responses[4].result).toBeOk(
expect(finalizeMint(1).result).toBeOk(Cl.bool(true));
expect(requestBurn(mintAmount).result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
);
});
@@ -159,44 +79,40 @@ describe(contracts.endpoint, () => {
it('can finalize burn', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
goToNextRequestCycle();
expect(fundStrategy(mintAmount).result).toBeOk(Cl.uint(mintAmount));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay + 1);
const burnResponses = requestBurn();
expect(burnResponses[0].result).toBeOk(Cl.uint(0));
expect(burnResponses[1].result).toBeOk(Cl.bool(true));
expect(burnResponses[2].result).toBeOk(Cl.uint(mintAmount));
expect(burnResponses[3].result).toBeOk(Cl.uint(mintAmount));
expect(burnResponses[4].result).toBeOk(
expect(finalizeMint(1).result).toBeOk(Cl.bool(true));
expect(requestBurn(mintAmount).result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
);
const responses = simnet.mineBlock([
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], user),
]);
expect(responses[0].result).toBeOk(Cl.uint(1e6));
expect(responses[1].result).toBeOk(Cl.uint(mintAmount));
expect(responses[2].result).toBeOk(Cl.bool(true));
expect(responses[3].result).toBeErr(Cl.uint(7007));
expect(responses[1].result).toBeOk(Cl.bool(true));
expect(responses[2].result).toBeErr(Cl.uint(7007));
});
it('can revoke burn', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
goToNextRequestCycle();
expect(fundStrategy(mintAmount).result).toBeOk(Cl.uint(mintAmount));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay + 1);
const burnResponses = requestBurn();
expect(burnResponses[0].result).toBeOk(Cl.uint(0));
expect(burnResponses[1].result).toBeOk(Cl.bool(true));
expect(burnResponses[2].result).toBeOk(Cl.uint(mintAmount));
expect(burnResponses[3].result).toBeOk(Cl.uint(mintAmount));
expect(burnResponses[4].result).toBeOk(
expect(finalizeMint(1).result).toBeOk(Cl.bool(true));
expect(requestBurn(mintAmount).result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
);
@@ -204,7 +120,7 @@ describe(contracts.endpoint, () => {
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], user),
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
]);
expect(responses[0].result).toBeOk(Cl.uint(1e6));
expect(responses[1].result).toBeErr(Cl.uint(3000));
@@ -215,7 +131,7 @@ describe(contracts.endpoint, () => {
it('can interact with strategies', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
const cycle = (
simnet.callReadOnlyFn(
@@ -239,7 +155,7 @@ describe(contracts.endpoint, () => {
simnet.mineEmptyBlocks(blocksToMine - 100);
let responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.list([Cl.uint(mintAmount)])], bot),
tx.callPublicFn(
contracts.manager,
@@ -261,15 +177,14 @@ describe(contracts.endpoint, () => {
simnet.mineEmptyBlocks(mintDelay + 1); // mint-delay
responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(mintAmount)], user),
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(1e6)], user),
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'request-burn', [Cl.uint(mintAmount)], user),
tx.callPublicFn(contracts.endpoint, 'request-burn', [Cl.uint(1e6)], user),
tx.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], bot),
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot),
]);
expect(responses[0].result).toBeOk(Cl.bool(true));
expect(responses[1].result).toBeOk(
@@ -280,8 +195,7 @@ describe(contracts.endpoint, () => {
expect(responses[4].result).toBeErr(Cl.uint(3000)); // not authorized
expect(responses[5].result).toBeOk(Cl.uint(1e6)); // refund 1 stx
expect(responses[6].result).toBeOk(Cl.uint(0)); // refund 0 stx
expect(responses[7].result).toBeOk(Cl.uint(mintAmount)); // rebase mintAmount stx
expect(responses[8].result).toBeErr(Cl.uint(7006)); // request pending
expect(responses[7].result).toBeErr(Cl.uint(7006)); // request pending
// refund remaining stx after unlock
goToNextCycle();
@@ -289,7 +203,7 @@ describe(contracts.endpoint, () => {
responses = simnet.mineBlock([
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot),
]);
expect(responses[0].result).toBeOk(Cl.uint(mintAmount - 1e6));
expect(responses[1].result).toBeOk(Cl.bool(true));
@@ -313,12 +227,12 @@ describe(contracts.endpoint, () => {
goToNextCycle(); // go to the next cycle
simnet.mineEmptyBlocks(mintDelay + 1); // mint-delay
response = simnet.callPublicFn(contracts.rebase1, 'rebase', [], oracle);
response = simnet.callPublicFn(contracts.endpoint, 'rebase', [], oracle);
expect(response.result).toBeOk(Cl.uint(0));
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
response = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
expect(response.result).toBeOk(Cl.bool(true));
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(2)], bot);
response = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(2)], bot);
expect(response.result).toBeOk(Cl.bool(true));
response = simnet.callPublicFn(
@@ -350,7 +264,7 @@ describe(contracts.endpoint, () => {
],
manager
);
response = simnet.callPublicFn(contracts.rebase1, 'rebase', [], oracle);
response = simnet.callPublicFn(contracts.endpoint, 'rebase', [], oracle);
expect(response.result).toBeOk(Cl.uint(100_000_100e6));
response = simnet.callReadOnlyFn(
@@ -375,7 +289,7 @@ describe(contracts.endpoint, () => {
response = simnet.transferSTX(1_000_000e6, `${simnet.deployer}.fastpool-member3`, oracle);
response = simnet.transferSTX(1_000_000e6, `${simnet.deployer}.fastpool-member4`, oracle);
response = simnet.callPublicFn(contracts.rebase1, 'rebase', [], oracle);
response = simnet.callPublicFn(contracts.endpoint, 'rebase', [], oracle);
expect(response.result).toBeOk(Cl.uint(104_000_100e6));
response = simnet.callReadOnlyFn(
@@ -398,17 +312,17 @@ describe(contracts.endpoint, () => {
it('can set up amm pool', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
goToNextCycle(); // go to the next cycle
const finaliseErr = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
const finaliseErr = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
expect(finaliseErr.result).toBeErr(Cl.uint(7006));
simnet.mineEmptyBlocks(mintDelay + 1); // mint-delay
let responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(
contracts.amm,
'create-pool',
@@ -432,15 +346,17 @@ describe(contracts.endpoint, () => {
let response;
// request and finalize mint for 1m STX
response = requestMint();
expect(response.result).toBeOk(Cl.uint(1));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay);
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
expect(response.result).toBeOk(Cl.bool(true));
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
// request burn
requestBurn();
goToNextRequestCycle();
expect(fundStrategy(mintAmount).result).toBeOk(Cl.uint(mintAmount));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay + 1);
expect(finalizeMint(1).result).toBeOk(Cl.bool(true));
expect(requestBurn(1e6).result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
);
// transfer burn of 1 stx
response = simnet.callPublicFn(
@@ -456,7 +372,7 @@ describe(contracts.endpoint, () => {
);
simnet.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
(response = simnet.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot));
(response = simnet.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot));
expect(response.result).toBeOk(Cl.bool(true));
// check that bot received stx

View File

@@ -1,326 +0,0 @@
// SPDX-License-Identifier: BUSL-1.1
import { tx } from '@hirosystems/clarinet-sdk';
import { Cl, TupleCV } from '@stacks/transactions';
import { describe, expect, it } from 'vitest';
import { createClientMockSetup } from './clients/mock-client';
const {
contracts,
prepareTest,
user,
oracle,
bot,
manager,
requestMint: requestMintLib,
createPayload,
goToNextCycle,
getRequestCycle,
getRewardCycle,
getBlocksToStartOfCycle,
} = createClientMockSetup();
const mintDelay = 144;
const requestMint = () => requestMintLib(100e6);
const requestBurn = (payload: Uint8Array) =>
simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.uint(100e6)], manager),
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user),
]);
describe(contracts.endpoint, () => {
it('can request mint', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
const response = requestMint();
expect(response.result).toBeOk(Cl.uint(1));
});
it('can finalize mint', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
goToNextCycle();
const finaliseErr = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
expect(finaliseErr.result).toBeErr(Cl.uint(7006));
simnet.mineEmptyBlocks(mintDelay);
let responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], user),
]);
expect(responses[0].result).toBeOk(Cl.bool(true));
expect(responses[1].result).toBeErr(Cl.uint(7007));
});
it('can revoke mint', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
let responses = simnet.mineBlock([
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], user),
]);
expect(responses[0].result).toBeErr(Cl.uint(3000));
expect(responses[1].result).toBeOk(Cl.bool(true));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay); // mint-delay
responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
]);
expect(responses[0].result).toBeErr(Cl.uint(7007));
});
it('can request burn', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay);
const payload = createPayload(100e6);
const responses = requestBurn(payload);
expect(responses[0].result).toBeOk(Cl.uint(0));
expect(responses[1].result).toBeOk(Cl.bool(true));
expect(responses[2].result).toBeOk(Cl.uint(100e6));
expect(responses[3].result).toBeOk(Cl.uint(100e6));
expect(responses[4].result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
);
});
it('can finalize burn', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay);
const payload = createPayload(100e6);
const burnResponses = requestBurn(payload);
expect(burnResponses[0].result).toBeOk(Cl.uint(0));
expect(burnResponses[1].result).toBeOk(Cl.bool(true));
expect(burnResponses[2].result).toBeOk(Cl.uint(100e6));
expect(burnResponses[3].result).toBeOk(Cl.uint(100e6));
expect(burnResponses[4].result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
);
const responses = simnet.mineBlock([
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], manager),
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], user),
]);
expect(responses[0].result).toBeOk(Cl.uint(100e6));
expect(responses[1].result).toBeOk(Cl.uint(100e6));
expect(responses[2].result).toBeOk(Cl.bool(true));
expect(responses[3].result).toBeErr(Cl.uint(7007));
});
it('can revoke burn', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay);
const payload = createPayload(100e6);
const burnResponses = requestBurn(payload);
expect(burnResponses[0].result).toBeOk(Cl.uint(0));
expect(burnResponses[1].result).toBeOk(Cl.bool(true));
expect(burnResponses[2].result).toBeOk(Cl.uint(100e6));
expect(burnResponses[3].result).toBeOk(Cl.uint(100e6));
expect(burnResponses[4].result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
);
const responses = simnet.mineBlock([
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], manager),
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], user),
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
]);
expect(responses[0].result).toBeOk(Cl.uint(100e6));
expect(responses[1].result).toBeErr(Cl.uint(3000));
expect(responses[2].result).toBeOk(Cl.bool(true));
expect(responses[3].result).toBeErr(Cl.uint(7007));
});
it('can request burn and finalized immediately', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
let response;
response = simnet.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user);
expect(response.result).toBeErr(Cl.uint(1)); // not enough funds
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay);
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
expect(response.result).toBeOk(Cl.bool(true));
expect(response.events[2].event).toBe('nft_burn_event');
response = simnet.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user);
expect(response.result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.buffer(new Uint8Array([1])) })
);
// no nft minted
expect(simnet.callReadOnlyFn(contracts.burnNft, 'get-last-token-id', [], user).result).toBeOk(
Cl.uint(0)
);
});
it('can interact with strategies', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
const cycle = getRewardCycle();
const blocksToMine = getBlocksToStartOfCycle(cycle + 1n);
simnet.mineEmptyBlocks(blocksToMine - 100);
let responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.uint(100e6)], bot),
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.uint(100e6)], manager),
]);
expect(responses[0].result).toBeErr(Cl.uint(7006));
expect(responses[1].result).toBeErr(Cl.uint(1000));
expect(responses[2].result).toBeOk(Cl.uint(100e6));
simnet.mineEmptyBlocks(99); // go to the next cycle
simnet.mineEmptyBlocks(mintDelay);
responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user),
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], bot),
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], manager),
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], manager),
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
]);
expect(responses[0].result).toBeOk(Cl.bool(true));
expect(responses[1].result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
);
expect(responses[2].result).toBeErr(Cl.uint(7006));
expect(responses[3].result).toBeErr(Cl.uint(1000));
expect(responses[4].result).toBeOk(Cl.uint(100e6));
expect(responses[5].result).toBeErr(Cl.uint(1));
expect(responses[6].result).toBeOk(Cl.uint(100e6));
expect(responses[7].result).toBeOk(Cl.bool(true));
});
it('can set up amm pool', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
goToNextCycle();
const finaliseErr = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
expect(finaliseErr.result).toBeErr(Cl.uint(7006));
simnet.mineEmptyBlocks(mintDelay);
let responses = simnet.mineBlock([
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
tx.callPublicFn(
contracts.amm,
'create-pool',
[
Cl.principal(simnet.deployer + '.' + contracts.wstx),
Cl.principal(simnet.deployer + '.' + contracts.wlqstx),
Cl.uint(1e8),
Cl.principal(user),
Cl.uint(1e8),
Cl.uint(1e8),
],
user
),
]);
expect(responses[0].result).toBeOk(Cl.bool(true));
expect(responses[1].result).toBeOk(Cl.bool(true));
});
it('operator extension works', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
let responses = simnet.mineBlock([
tx.callPublicFn(
contracts.operators,
'propose',
[Cl.contractPrincipal(simnet.deployer, contracts.proposal)],
bot
),
tx.callPublicFn(
contracts.operators,
'propose',
[Cl.contractPrincipal(simnet.deployer, contracts.proposal)],
simnet.deployer
),
]);
expect(responses[0].result).toBeErr(Cl.uint(1001));
expect(responses[1].result).toBeOk(Cl.bool(false));
responses = simnet.mineBlock([
tx.callPublicFn(
contracts.operators,
'signal',
[Cl.contractPrincipal(simnet.deployer, contracts.proposal), Cl.bool(true)],
bot
),
tx.callPublicFn(
contracts.operators,
'signal',
[Cl.contractPrincipal(simnet.deployer, contracts.proposal), Cl.bool(true)],
manager
),
]);
expect(responses[0].result).toBeErr(Cl.uint(1001));
expect(responses[1].result).toBeOk(Cl.bool(true));
});
it('request cycle respects cutoff', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(getRequestCycle()).toBe(0n);
// cycle length - prepare cycle length - cutoff - blocks for deployment and prepare
simnet.mineEmptyBlocks(1050 - 50 - 300 - 6);
// we are at the end of request cycle 0
expect(simnet.blockHeight).toBe(699);
expect(getRequestCycle()).toBe(0n);
simnet.mineEmptyBlocks(1050); // cycle length
// we are at end of request cycle 1
expect(simnet.blockHeight).toBe(1749);
expect(getRequestCycle()).toBe(1n);
simnet.mineEmptyBlocks(1);
// we are at beginning of request cycle 2
// that is 1050 + 1050 - 50 - 100
expect(simnet.blockHeight).toBe(1750);
expect(getRequestCycle()).toBe(2n);
const response = requestMint();
expect(response.result).toBeOk(Cl.uint(1));
expect(response.events[0].event).toBe('stx_transfer_event');
expect(response.events[1].event).toBe('nft_mint_event');
expect(response.events[2].event).toBe('print_event');
expect(
((response.events[2].data.value as TupleCV).data.details as TupleCV).data['requested-at']
).toBeUint(2);
});
});

View File

@@ -11,7 +11,7 @@ describe('lisa token', () => {
requestMint(100e6);
goToNextCycle();
simnet.mineEmptyBlocks(mintDelay);
simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
});
sip10Tests(contracts.lqstx);