admin管理员组

文章数量:1126348

I'm working on a smart contract test using ethers.js, and I'm facing an issue with rounding errors when comparing ether balances of accounts after executing transactions. Specifically, the problem arises when I try to test the balance changes for an auction system.

I'm using ethers.js v6.

In my test, I am calculating the fee amount and then distributing the ether to the seller and refunding the buyer. However, after the transaction, I encounter a difference of 1 wei when comparing the balance changes for the smart contract, the buyer, and the seller. The issue seems to be related to rounding discrepancies in the calculations, and I need to account for this while testing.

Logic:

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);
}

Test method:

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);
    });

Test result screenshot

本文标签: