How to correctly import SafeMath.sol into contract - solidity

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;

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

How to check values of a variables and functions in solidity like javascript via console.log

How to check values of a variables and functions in solidity like javascript via console.log? Because i need visibility of results for deep understanding.
I am newbie...
i tried hardhat but need more understand.
I'm a newbie too, but I know this (I think)!
There is no console in solidity, you need to write a function for this, or just put it public in the variable itself!
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Value {
uint public num; //add "public" to see the value
function add(uint _num) external{
num += _num;
}
//this function is for returning value
function viewNum() public view returns(uint){
return(num);
}
}
Also use the Remix editor, it's in the browser. There are plenty of videos on the internet!
If you are using hardhat, then you can use console.sol.
You need to import it into your contract.
import "hardhat/console.sol";
Now, you are able to log your variable while you are working.
console.log(__your_variable__);
If you are still looking to log your variables once you deploy your contract, then you need to use event functionality.
Import hardhat console:
import "hardhat/console.sol";
Use console log in your contract
console.log(variable); //Variable value
console.log(1234); //direct value

Execution is reverted in Solidity and Remix

I've wrote a simple code for fetching ETH price by using Chainlink interfaces as below:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "#chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
contract ABI {
AggregatorV3Interface internal priceFeed;
constructor() public {
priceFeed = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);
}
function latestPrice() public view returns (int256) {
(, int256 answer,,,) = priceFeed.latestRoundData();
return answer;
}
}
The problem is when is being compiled by Remix, it has no problem but after execution it throws the error below:
call to ContractName.FunctionName errored: execution reverted
Do you think what the problem is?
Because your question didn't specify on which network you're running the script, I'm assuming that you're using the Remix VM emulator.
The specified Chainlink contract is available on Ethereum mainnet only. Any other network (including the emulator) does not have this contract deployed on this address.
To use the data feed contract in Remix, you can create a local fork of the mainnet, and then connect to the local network in the IDE.
Change ENVIRONMENT to Injected Web3 in Remix IDE and connect to metamask. For example, if you are using Kovan network use address as mentioned in the docs.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract PriceConsumerV3 {
AggregatorV3Interface internal priceFeed;
/**
* Network: Kovan
* Aggregator: ETH/USD
* Address: 0x9326BFA02ADD2366b30bacB125260Af641031331
*/
constructor() {
priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
}
/**
* Returns the latest price
*/
function getLatestPrice() public view returns (int) {
(
/*uint80 roundID*/,
int price,
/*uint startedAt*/,
/*uint timeStamp*/,
/*uint80 answeredInRound*/
) = priceFeed.latestRoundData();
return price;
}
}

Using Strings for uint256 not working with ERC721EnumerableUpgradeable

just like the title says I cannot get using Strings to compile, I keep getting the identifier not found.
This is the start of my .sol contract
import "#openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol";
import "#openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "#openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "#openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";
contract NFT is Initializable, StringsUpgradeable, ERC721EnumerableUpgradeable, OwnableUpgradeable {
using Strings for uint256;
Please help!
Thank you!
The imported StringsUpgradeable.sol file contains a library named StringsUpgradeable - not Strings.
Also, since it's a library, it cannot be inherited from, so you need to remove it from the list of the NFT parents.
pragma solidity ^0.8;
import "#openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol";
import "#openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "#openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "#openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";
// removed `StringsUpgradable` from the parents list
contract NFT is Initializable, ERC721EnumerableUpgradeable, OwnableUpgradeable {
// replaced `Strings` to `StringsUpgradable`
using StringsUpgradeable for uint256;
}

Cannot Compile StorageFactory.sol because "not found contracts/SimpleStorage.sol

I am doing the Solidity, Blockchain, and Smart Contract Course – Beginner to Expert Python Tutorial from freeCodeCamp and Patrick AlphaC
https://github.com/PatrickAlphaC/storage_factory
Below is my code image from my IDE too here
// SPDX-License_Identifier: MIT
pragma solidity ^0.8.0;
import "./SimpleStorage.sol";
contract StorageFactory {
SimpleStorage[] public simpleStorageArray;
function createSimpleStorageContact() public {
SimpleStorage simpleStorage = new SimpleStorage();
simpleStorageArray.push(simpleStorage);
}
}
and I am getting the error:
not found contracts/SimpleStorage.sol
even though all the files are spelt correctly and in the same folder.
Please help as I am trying to follow along with the tutorial and don't want to get left behind.
In your picture your filename is wrong. You write SimpleSorage but it must be SimpleStorage. (Note the missing t in Storage.)

Invalid input source specified

getting an Invalid input source specified error with the following import when building a smart contract using the remix IDE
import "https://github.com/aave/flashloan-box/blob/Remix/contracts/aave/FlashLoanReceiverBase.sol";
Put together a super basic example smart contract in remix. It compiles just fine if I dont include the import statement.
pragma solidity ^0.6.6;
import "https://github.com/aave/flashloan-box/blob/Remix/contracts/aave/FlashLoanReceiverBase.sol";
contract Inbox {
string public message;
constructor(string memory initialMessage) public {
message = initialMessage;
}
function setMessage(string memory newMessage) public {
message = newMessage;
}
function getMessage() public view returns (string memory) {
return message;
}
}
This issue is happening because of the nested import using relative path.
The FlashLoanReceiverBase.sol is trying to import relative path ./IFlashLoanReceiver.sol (not absolute path https://github.com/aave/flashloan-box/blob/Remix/contracts/aave/IFlashLoanReceiver.sol).
Since you don't have a contract named IFlashLoanReceiver.sol in the same folder as your own contract, this import fails.
Best solution would be to submit a PR to the aave/flashloan-box repository making all import paths absolute.