191 lines
7.5 KiB
TypeScript
191 lines
7.5 KiB
TypeScript
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
|
|
import { Cell, toNano } from '@ton/core';
|
|
import { MainBalance } from '../wrappers/MainBalance';
|
|
import '@ton/test-utils';
|
|
import { compile } from '@ton/blueprint';
|
|
import { randomAddress } from '@ton/test-utils';
|
|
import { fromNano } from 'ton';
|
|
import { hex } from "../build/MainBalance.compiled.json";
|
|
import contractConfig, { servicePercent, tokenPercent } from '../config/contract.config';
|
|
import { calcPercent } from '../scripts/utils';
|
|
|
|
describe('MainBalance', () => {
|
|
let code: Cell;
|
|
|
|
beforeAll(async () => {
|
|
// code = await compile('MainBalance');
|
|
code = Cell.fromBoc(Buffer.from(hex, "hex"))[0];
|
|
});
|
|
|
|
let blockchain: Blockchain;
|
|
let owner: SandboxContract<TreasuryContract>;
|
|
let newOwner: SandboxContract<TreasuryContract>;
|
|
let user: SandboxContract<TreasuryContract>;
|
|
let anotherUser: SandboxContract<TreasuryContract>;
|
|
let mainBalance: SandboxContract<MainBalance>;
|
|
|
|
let serviceAddress: SandboxContract<TreasuryContract>;
|
|
let tokenAddress: SandboxContract<TreasuryContract>;
|
|
|
|
beforeEach(async () => {
|
|
blockchain = await Blockchain.create();
|
|
|
|
owner = await blockchain.treasury('owner');
|
|
newOwner = await blockchain.treasury('newOwner');
|
|
user = await blockchain.treasury('user');
|
|
anotherUser = await blockchain.treasury('anotherUser');
|
|
serviceAddress = await blockchain.treasury('serviceAddress');
|
|
tokenAddress = await blockchain.treasury('tokenAddress');
|
|
|
|
mainBalance = blockchain.openContract(MainBalance.createFromConfig({
|
|
ownerAddress: owner.address.toString(),
|
|
depositFunds: 0,
|
|
serviceAddress: serviceAddress.address.toString(),
|
|
tokenAddress: tokenAddress.address.toString()
|
|
}, code));
|
|
|
|
const deployResult = await mainBalance.sendDeploy(owner.getSender(), toNano(0.05));
|
|
|
|
expect(deployResult.transactions).toHaveTransaction({
|
|
from: owner.address,
|
|
to: mainBalance.address,
|
|
deploy: true,
|
|
success: true,
|
|
});
|
|
|
|
});
|
|
|
|
it('should deploy', async () => {
|
|
// the check is done inside beforeEach
|
|
// blockchain and mainBalance are ready to use
|
|
});
|
|
|
|
it("should deposit funds", async () => {
|
|
const depositResult = await mainBalance.sendDeposit(user.getSender(), toNano('10'));
|
|
|
|
expect(depositResult.transactions).toHaveTransaction({
|
|
from: user.address,
|
|
to: mainBalance.address,
|
|
success: true,
|
|
});
|
|
|
|
expect(+fromNano(await mainBalance.getBalance())).toBeCloseTo(10, 0.05);
|
|
expect(+fromNano(await mainBalance.getDepositFunds())).toBeCloseTo(calcPercent(10, contractConfig.totalFee), 0.05);
|
|
});
|
|
|
|
it("should change owner address", async () => {
|
|
await mainBalance.sendChangeOwnerAddress(owner.getSender(), newOwner.address);
|
|
|
|
expect((await mainBalance.getOwnerAddress()).toString()).toBe(newOwner.address.toString());
|
|
});
|
|
|
|
it("shouldn't change owner address", async () => {
|
|
await mainBalance.sendChangeOwnerAddress(user.getSender(), newOwner.address);
|
|
|
|
expect((await mainBalance.getOwnerAddress()).toString()).not.toBe(newOwner.address.toString());
|
|
});
|
|
|
|
it("should change only service address", async () => {
|
|
const changeResult = await mainBalance.sendChangeServiceAddress(owner.getSender(), newOwner.address, tokenAddress.address);
|
|
const { serviceAddr } = await mainBalance.getServiceAddress();
|
|
|
|
expect(changeResult.transactions).toHaveTransaction({
|
|
from: owner.address,
|
|
to: mainBalance.address,
|
|
success: true,
|
|
});
|
|
|
|
expect(serviceAddr.toString()).toBe(newOwner.address.toString());
|
|
});
|
|
|
|
it("should transfer service fee", async () => {
|
|
await mainBalance.sendDeposit(user.getSender(), toNano(10));
|
|
await mainBalance.sendDeposit(user.getSender(), toNano(20));
|
|
await mainBalance.sendDeposit(anotherUser.getSender(), toNano(50));
|
|
|
|
let totalBalance = 10 + 20 + 50; // 80
|
|
const serviceFee = calcPercent(totalBalance, servicePercent);
|
|
const tokenFee = calcPercent(totalBalance, tokenPercent);
|
|
|
|
const tranferResult = await mainBalance.sendTransferServiceFee(owner.getSender(), toNano(serviceFee), toNano(tokenFee));
|
|
|
|
expect(tranferResult.transactions).toHaveTransaction({
|
|
from: owner.address,
|
|
to: mainBalance.address,
|
|
success: true,
|
|
});
|
|
|
|
expect(+fromNano(await mainBalance.getDepositFunds())).toBe(0);
|
|
|
|
expect(tranferResult.transactions).toHaveTransaction({
|
|
from: mainBalance.address,
|
|
to: serviceAddress.address,
|
|
success: true,
|
|
});
|
|
|
|
expect(tranferResult.transactions).toHaveTransaction({
|
|
from: mainBalance.address,
|
|
to: tokenAddress.address,
|
|
success: true,
|
|
});
|
|
});
|
|
|
|
it("shouldn't transfer service fee when funds exceeded", async () => {
|
|
await mainBalance.sendDeposit(user.getSender(), toNano(10));
|
|
await mainBalance.sendDeposit(user.getSender(), toNano(20));
|
|
await mainBalance.sendDeposit(anotherUser.getSender(), toNano(50));
|
|
|
|
let totalBalance = 10 + 20 + 50; // 80
|
|
const serviceFee = calcPercent(totalBalance, servicePercent) + 10;
|
|
const tokenFee = calcPercent(totalBalance, tokenPercent) + 10;
|
|
|
|
const tranferResult = await mainBalance.sendTransferServiceFee(owner.getSender(), toNano(serviceFee), toNano(tokenFee));
|
|
|
|
expect(tranferResult.transactions).toHaveTransaction({
|
|
from: owner.address,
|
|
to: mainBalance.address,
|
|
success: false,
|
|
exitCode: contractConfig.error.FUNDS_EXCEED
|
|
});
|
|
});
|
|
|
|
it("should withdraw user coins", async () => {
|
|
await mainBalance.sendDeposit(user.getSender(), toNano(20));
|
|
await mainBalance.sendDeposit(user.getSender(), toNano(40));
|
|
await mainBalance.sendDeposit(anotherUser.getSender(), toNano(90));
|
|
|
|
let totalBalance = 20 + 40 + 90; // 150
|
|
const serviceFee = calcPercent(totalBalance, servicePercent);
|
|
const tokenFee = calcPercent(totalBalance, tokenPercent);
|
|
|
|
await mainBalance.sendTransferServiceFee(owner.getSender(), toNano(serviceFee), toNano(tokenFee));
|
|
|
|
let userWithdrawAmount = toNano(60 - calcPercent(60, contractConfig.totalFee)); // data from backend, - 10% fee
|
|
|
|
const withdrawResult = await mainBalance.sendWithdraw(owner.getSender(), user.address, userWithdrawAmount);
|
|
|
|
expect(withdrawResult.transactions).toHaveTransaction({
|
|
from: mainBalance.address,
|
|
to: user.address,
|
|
value: userWithdrawAmount,
|
|
success: true,
|
|
});
|
|
|
|
expect(+fromNano(await mainBalance.getDepositFunds())).toBe(0);
|
|
console.log("smc balance after transfer fee and withdraw", fromNano(await mainBalance.getBalance()));
|
|
|
|
let anotherUserWithdrawAmount = toNano(90 - calcPercent(90, contractConfig.totalFee)); // data from backend, - 10% fee
|
|
|
|
const secondWithdrawResult = await mainBalance.sendWithdraw(owner.getSender(), anotherUser.address, anotherUserWithdrawAmount);
|
|
|
|
expect(secondWithdrawResult.transactions).toHaveTransaction({
|
|
from: mainBalance.address,
|
|
to: anotherUser.address,
|
|
value: anotherUserWithdrawAmount,
|
|
success: true,
|
|
});
|
|
|
|
console.log("smc balance after another withdraw", fromNano(await mainBalance.getBalance()));
|
|
});
|
|
});
|