0

I'm doing a simple Dapp where I register a star as an NFT, using openzeppelin ERC721 contract, and then I can put it up for sale and buy it. In truffle I'm writing a test where I create a star, put it for sale then buy it. I get the balance of the buyer before and after the purchase, compute the difference and assert if it is the same as the price of the star. I took into account the gas used but there is still a tiny difference I can't understand. Here is my code:


Contract function

function buyStar(uint256 _tokenId) public  payable {
    require(starsForSale[_tokenId] > 0, "The Star should be up for sale");
    uint256 starCost = starsForSale[_tokenId];
    address ownerAddress = ownerOf(_tokenId);
    require(msg.value > starCost, "You need to have enough Ether");
    transferFrom(ownerAddress, msg.sender, _tokenId); // We can't use _addTokenTo or_removeTokenFrom functions, now we have to use _transferFrom
    address payable ownerAddressPayable = payable(ownerAddress); // We need to make this conversion to be able to use transfer() function to transfer ethers
    ownerAddressPayable.transfer(starCost);
    
    if(msg.value > starCost) {
        payable(msg.sender).transfer(msg.value - starCost);
    }

Truffle test

it('lets user2 buy a star and decreases its balance in ether', async() => {
    let instance = await StarNotary.deployed();
    let user1 = accounts[1];
    let user2 = accounts[2];
    let starId = 5;
    let starPrice = web3.utils.toWei(".01", "ether");
    let balance = web3.utils.toWei(".05", "ether");
    await instance.createStar('awesome star 4', starId, {from: user1});
    await instance.putStarUpForSale(starId, starPrice, {from: user1});
    let balanceOfUser1BeforeTransaction = await web3.eth.getBalance(user2);
    const balanceOfUser2BeforeTransaction = await web3.eth.getBalance(user2);
    
    const receipt = await instance.buyStar(starId, {from: user2, value: balance});

   
    const tx = await web3.eth.getTransaction(receipt.tx);
    const gasCost = tx.gasPrice * receipt.receipt.gasUsed;
    console.log(`GasCost + Star Price: ${Number(gasCost) + Number(starPrice)}`);

    const balanceAfterUser2BuysStar = await web3.eth.getBalance(user2);
   
    let value = Number(balanceOfUser2BeforeTransaction) - Number(balanceAfterUser2BuysStar);
    console.log(`Difference: ${ value - (Number(gasCost) + Number(starPrice))}`);
    
    assert.equal(value, starPrice);
  });

Test output:

test output

1
  • Maybe not the answer but you can’t just cast to Number . You need to use BigNumbers library when u calculate something
    – Majd TL
    Commented Apr 4, 2022 at 18:28

1 Answer 1

1

I used the BigNumbers library as suggested by @Majd, to perform the calculations and it worked as expected.

    const gasPrice = new web3.utils.BN(tx.gasPrice);
    const gasUsage = new web3.utils.BN(receipt.receipt.gasUsed);
    const price = new web3.utils.BN(starPrice);

    const gasCost = gasPrice.mul(gasUsage);

    const balanceAfterUser2BuysStar = await web3.eth.getBalance(user2);
   
    let value = new web3.utils.BN(balanceOfUser2BeforeTransaction).sub(new web3.utils.BN(balanceAfterUser2BuysStar));
    const x = new web3.utils.BN(value).sub(gasCost)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.