可靠性测试。 1 伟问题。在ethers.js合约中测试余额变化时如何处理舍入差异?

问题描述 投票:0回答:1

我正在使用 ethers.js 进行智能合约测试,在执行交易后比较帐户的以太币余额时,我遇到了舍入错误的问题。具体来说,当我尝试测试拍卖系统的余额变化时,问题就出现了。

我正在使用 ethers.js v6。

在我的测试中,我正在计算费用金额,然后将以太币分配给卖方并退还给买方。然而,交易结束后,我在比较智能合约、买方和卖方的余额变化时遇到了 1 wei 的差异。这个问题似乎与计算中的舍入差异有关,我需要在测试时考虑到这一点。

逻辑:

function buy(uint index) external payable activeAuction(index) {
    Auction storage auction = auctions[index];
    require(block.timestamp < auction.endAt, "Auction has ended");
    uint price = getPriceFor(index);
    require(msg.value >= price, "Not enough money");
    auction.stopped = true;
    auction.finalPrice = price;

    //refund
    uint refund = msg.value - price;
    if(refund > 0) {
    payable(msg.sender).transfer(refund);
    }

    auction.seller.transfer(price - ((price * FEE)/100));

    emit AuctionEnded(index, price, msg.sender);
}

测试方法:

it("Should allow to buy and refund", async () => {
        const FEE = 10; 
        
        const oneEtherInWei = ethers.parseEther("1");  // 1 ETH = 1e18 wei
        const twoEtherInWei = ethers.parseEther("2");  // 2 ETH = 2e18 wei

        await expect(smartContract.connect(seller).createAuction(
            oneEtherInWei,  
            FEE,
            "test item",
            60
        ));
        
        const tx = await smartContract.connect(buyer).buy(0, { value: twoEtherInWei });
        await tx.wait();
        
        const feeAmount = (parseFloat(oneEtherInWei.toString()) * FEE) / 100; 
        console.log("feeAmount :", feeAmount);
        
        const moneyForSeller = parseFloat(oneEtherInWei.toString()) - feeAmount;
        console.log("moneyForSeller :", moneyForSeller);
        
        const moneyLeftOnContract = parseFloat(oneEtherInWei.toString()) - moneyForSeller;
        console.log("moneyLeftOnContract :", moneyLeftOnContract);


        await expect(tx).to.changeEtherBalance(smartContract.target, moneyLeftOnContract.toString()) // Перевірка зміни балансу смарт-контракту
        await expect(tx).to.changeEtherBalance(buyer.address, (parseFloat(twoEtherInWei) * -1).toString()) // Перевірка зміни балансу покупця
        await expect(tx).to.changeEtherBalance(seller.address, moneyForSeller.toString()) // Перевірка зміни балансу продавця

        
        
        const price = await smartContract.auctions(0).finalPrice;
        expect(tx).to.emit(smartContract, "AuctionEnded")
            .withArgs(0, price, buyer);
    });

测试结果截图

blockchain solidity smartcontracts ethers.js hardhat
1个回答
0
投票

我会尝试在 BigNumber 中进行计算,而不是全部转换为浮点数。所以你没有四舍五入。

//const feeAmount = (parseFloat(oneEtherInWei.toString()) * FEE) / 100;
const feeAmount = oneEtherInWei.mul(FEE).div(100);

//const moneyForSeller = parseFloat(oneEtherInWei.toString()) - feeAmount;
const moneyForSeller = oneEtherInWei.sub(feeAmount);

//const moneyLeftOnContract = parseFloat(oneEtherInWei.toString()) - moneyForSeller;
const moneyLeftOnContract = oneEtherInWei.sub(moneyForSeller);
© www.soinside.com 2019 - 2024. All rights reserved.