+
Skip to content

Making sense of total fees #55

Open
@9oelM

Description

@9oelM

I have a question about tx.totalFees.coins. I genuinely cannot understand what this value is supposed to represent. In my case, I want to write a test on how much gas is spent for a series of transactions.

I've provided an example at https://github.com/9oelM/ton-sandbox-totalfees-bug.git. The test setup is simple:

  1. User wallet sends tx to ContractA (msg mode is 0)
  2. ContractA sends tx to ContractB (msg mode is 64)

In code, it is as simple as:

it('fees test', async () => {
        const increaser = await blockchain.treasury('increaser');
        const contractBTONBalanceBefore = await contractB.getBalance();

        const increaseResult = await contractA.sendIncrease(increaser.getSender(), {
            increaseBy: 1,
            value: toNano('0.05'),
        });

        expect(increaseResult.transactions).toHaveTransaction({
            from: increaser.address,
            to: contractA.address,
            success: true,
        });
        expect(increaseResult.transactions).toHaveTransaction({
            from: contractA.address,
            to: contractB.address,
            success: true,
        });

        printTransactionFees(increaseResult.transactions);

        const allFees = increaseResult.transactions.reduce((acc, tx) => {
            return acc + tx.totalFees.coins;
        }, 0n)
        
        const contractBTONBalanceAfter = await contractB.getBalance();
        console.log('contractB TON inflow', contractBTONBalanceAfter - contractBTONBalanceBefore);

        const lastTx = flattenTransaction(increaseResult.transactions[increaseResult.transactions.length - 1]);
        expect(lastTx.value! - lastTx.totalFees!).toBe(
            toNano('0.05') - allFees
        );
    });

printTransactionFees(increaseResult.transactions); prints:
Screenshot 2024-10-03 at 10 08 58

But I couldn't wrap my head around these numbers. I thought totalFees is supposed to be the sum of all total fees for a tx. In other words, $valueIn - valueOut = totalFees$. But this simply isn't the case:

  1. For index = 0, valueIn = 0.05 TON (we started with 0.05 TON) and valueOut = 0.0496 TON. valueIn - valueOut = 0.0004. But totalFees = 0.001613???
  2. Same for index = 1. valueIn = 0.0496 TON and valueOut = 0.046978 TON. valueIn - valueOut = 0.002622. But totalFees = 0.002296???

If totalFees were correctly calculated as total gas for the tx, toNano('0.05') - allFees would simply match the TON balance transferred to a contract, which is contractBTONBalanceAfter - contractBTONBalanceBefore. But this is not the case. In fact, lastTx.value - lastTx.totalFees == contractBTONBalanceAfter - contractBTONBalanceBefore != toNano('0.05') - allFees:

  • lastTx.value! - lastTx.totalFees! = 45904800n
  • contractBTONBalanceAfter - contractBTONBalanceBefore = 45904800n
  • toNano('0.05') - allFees = 45020139n

cc @krigga

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载