0

I am running this contract on VsCode + Solidity 0.8.13:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.13;
import "hardhat/console.sol";

contract Token {

   mapping(address => uint) balances;
   uint public totalSupply;

   constructor(uint _initialSupply) {
      balances[msg.sender] = totalSupply = _initialSupply;
      console.log(msg.sender);
 }

 function transfer(address _to, uint _value) public returns (bool) {
    require(balances[msg.sender] - _value >= 0);
    balances[msg.sender] -= _value;
    balances[_to] += _value;
    return true;
 }
}

That require in the transfer function should lead to an underflow if _value is greater than balances[msg.sender] but on my setup no revert is sent.

However if I use Remix with Solidity 0.8 I receive the revert while of course everything is fine with Solidity < 0.8 as this is a new feature.

Why is there seem to be no difference between Solidity version on VsCode instead? Anyone can reproduce that behavior?

Edit: I am testing it with this Typescript test using hardhat:

import { expect } from "chai";
import { BigNumber, Contract, Signer } from "ethers";
import { ethers } from "hardhat";
import { createChallenge, submitLevel } from "./utils";

let accounts: Signer[];
let eoa: Signer;
let accomplice: Signer;
let attacker: Contract;
let challenge: Contract; // challenge contract
let tx: any;

before(async () => {
accounts = await ethers.getSigners();
[eoa, accomplice] = accounts;
const challengeFactory = await ethers.getContractFactory(`Token`);
const challengeAddress = await createChallenge(`0x63bE8347A617476CA461649897238A31835a32CE`);
challenge = await challengeFactory.attach(challengeAddress);
});

it("solves the challenge", async function () {
   tx = await challenge
   .transfer("0x0000000000000000000000000000000000000000", 21);
   await tx.wait();
});

after(async () => {
   expect(await submitLevel(challenge.address), "level not solved").to.be.true;
 });

Thanks!

1 Answer 1

1

Make sure that you use the correct compiler.

Check that VSCode uses the correct version is linked to your project by right clicking the SOL file, then choose "Change global compiler version" and choose a suitable version.

I've tested this on VSCode with hardhat, using Solidity 0.8.4 and it reverted correctly -

reverted with panic code 0x11 (Arithmetic operation underflowed or overflowed outside of an unchecked block)

This is the hardhat test file I've used -

const { ethers } = require("hardhat");

describe("Test", async () => {

    let owner, second, test;

    beforeEach(async () => {
        [owner, second] = await ethers.getSigners();;
        const Test = await ethers.getContractFactory("Test");
        test = await Test.deploy(100);
        await test.deployed();
    });

    it("should revert, can't spend more than balance", async function () {
        expect(await test.connect(owner).transfer(second.address, 1000000)).to.be.reverted();
    });
});

hardhat.config.js -

module.exports = {
    solidity: "0.8.4"
};

In any case, you better change your check to one that doesn't have underflow issues -

require(balances[msg.sender] >= _value);
2
  • I am using hardhat and I have that setting correct on 0.8.13. I really do not understand. I edited the OP with also my typescript test that I am running with npx hardhat test test.ts. There is a security issue as this is from Ethernaut actually :) Could you please add the test you are using? Thanks
    – MarkTonner
    May 9, 2022 at 10:27
  • Thanks for the edit. Could you please also try with typescript test?
    – MarkTonner
    May 9, 2022 at 12:33

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.