How to correctly import SafeMath.sol into contract

Viewed 18745

This has been a problem I've been dealing with for a while now. My temporary solution has been to create a SafeMath.sol file in my Contracts directory and directly import it from there. However, I've been looking for a 'clearer solution' to this... Old way seemed to be directly importing it from a GitHub link, as seen in some repos and other stack overflow posts like such

However, the proper way do this seems to be installing the corresponding oz package (@openzeppelin/contracts-ethereum-package) and importing the file directly into the needed contract i.e.

import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";

However, using VSCode, I still get the error Source "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol" not found: File import callback not supported

That said, how can I properly import SafeMath?

EDIT: I am using pragma solidity ^0.6.0;

8 Answers

I looked through the node_modules for the package @openzeppelin/contracts. Here is the current correct import path as of posting:

import "@openzeppelin/contracts/utils/math/SafeMath.sol";

This is no longer needed with Solidity version 8

path is different in v 3.0 documentation

I used this:

import "@openzeppelin/contracts/math/SafeMath.sol";

Instead of this:

import "@openzeppelin/contracts/utils/math/SafeMath.sol";

Can be used in the following way:

pragma solidity ^0.5.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.3.0/contracts/math/SafeMath.sol";

contract contractForSafeMath {
    
    using SafeMath for uint;
    
    uint256 addResult;
    uint256 subResult;
    uint256 mulResult;
    uint256 divResult;
    uint256 modResult;
    
    uint public MAX_VALUE = 2**256 -1;
    //overflow
    uint256 overflowResult;
    
    function getResults(uint256 a, uint256 b) public{
         addResult = SafeMath.add(a,b);
         subResult = SafeMath.sub(a,b);
         mulResult = SafeMath.mul(a,b);
         divResult = SafeMath.div(a,b);
         modResult = SafeMath.mod(a,b);
         overflowResult = SafeMath.add(SafeMath.add ( (a**b), SafeMath.mul (SafeMath.mul (b, a), b)), (b** b));
    }
    
    function addResultVal(uint a, uint b) public view returns(uint256){
        return addResult;
    }
    
     function subResultVal() public view returns(uint256){
        return subResult;
    }
    
     function mulResultVal() public view returns(uint256){
        return mulResult;
    }
    
     function divResultVal() public view returns(uint256){
        return divResult;
    }
    
     function modResultVal() public view returns(uint256){
        return modResult;
    }
    
    function overflowResultVal() public view returns(uint256){
        return overflowResult;
    }
}

Go to the github page for any import you'll like to have for openzeppelin-contracts, "SafeMath" in this case, and copy the page url. Ex:

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";

Import the library right after pragma solidity. Then include it right after the opening of your contract.

pragma solidity ^x.x.x;

import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";

contract TheNameOfYourContract {
    using SafeMath for uint;
    .
    .
    ...
}

creating a project from npx hardhat (2.8.3) selecting advanced project and then having a folder structure like this:

project
  |--contracts
       |--mycontract.sol
  |--node_modules
  |--{other files & folders}

The error is gone if I import libraries like this inside mycontract.sol:

pragma solidity ^0.8.4;

import "../node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "../node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../node_modules/@openzeppelin/contracts/access/Ownable.sol";

... other code

But this will not compile at least with hardhat. So it appears Solhint (.solhint.json) requires to know exactly the import paths but it ignores by default (.solhintignore) the node_modules folder. By removing node_modules from .solhintignore and restarting VS Code it works for me.

No longer needed but import that works for pragma solidity ^0.6.0; would be: import "@chainlink/contracts/src/v0.6/vendor/SafeMathChainlink.sol";

Related