Type is not callable _isExcludedFromFee[(owner)] = true; - typeerror

My token contract with solidity 0.8.4 is catching:
TypeError: Type is not callable
_isExcludedFromFee[(owner)] = true;
^^^^^^^^
From:
constructor () {
_rOwned[_msgSender()] = _rTotal;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F);
// Create a uniswap pair for this new token
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), _uniswapV2Router.WETH());
// set the rest of the contract variables
uniswapV2Router = _uniswapV2Router;
_isExcludedFromFee[owner()] = true;
_isExcludedFromFee[address(this)] = true;
emit Transfer(address(0), _msgSender(), _tTotal);
initialize();
pause();
}
I believe it is "owner" that is causing the error, and will attach the Ownable and token contract below. There is an owner function that is typically included SafeMoon's Ownable that returns _owner but that just breaks everything more since I have newly declared address public owner.

Was able to correct by making these changes:
contract Ownable is Context {
// OWNER DATA
address public _owner;
address public _proposedOwner;
address private _oldOwner;
uint256 private _lockTime;
// OWNABLE EVENTS
event OwnershipTransferProposed(
address indexed currentOwner,
address indexed proposedOwner
);
event OwnershipTransferDisregarded(
address indexed oldProposedOwner
);
event OwnershipTransferred(
address indexed oldOwner,
address indexed newOwner
);
/**
* #dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* #dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* #dev Returns the address of the current owner.
*/
/**
* #dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* #dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* #dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function getUnlockTime() public view returns (uint256) {
return _lockTime;
}
//Locks the contract for owner for the amount of time provided
function lock(uint256 time) public virtual onlyOwner {
_oldOwner = _owner;
_owner = address(0);
_lockTime = block.timestamp + time;
emit OwnershipTransferred(_owner, address(0));
}
//Unlocks the contract for owner when _lockTime is exceeds
function unlock() public virtual {
require(_oldOwner == msg.sender, "You don't have permission to unlock");
require(block.timestamp > _lockTime , "Contract is locked until 7 days");
emit OwnershipTransferred(_owner, _oldOwner);
_owner = _oldOwner;
}
}

Related

I generated a flattened of my contract using Remix but it gives error: Definition of base has to precede definition of derived contract

I thibk the error is occurring because the contract "ERC721Burnable" is trying to inherit from two other contracts "Context" and "ERC721", but "Context" is not defined in the code you provided. So, the definition of a base contract must precede the definition of a derived contract.
How can I make sure that the definition of the "Context" contract is included before the definition of the "ERC721Burnable" contract. Additionally, How can I make sure that "Context" is defined in the same file or imported from a different file.
Bellow is the code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/common/ERC2981.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/utils/math/SafeMath.sol";
contract AliveNatureNFT is ERC721, ERC721Enumerable, ERC721URIStorage, ERC2981, Pausable, ERC721Burnable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
// percentage split for commission and liquidity pool
uint96 public commissionPercentage;
uint96 public liquidityPercentage;
// address of the commission recipient
address public commissionRecipient;
// address of the liquidity pool
address public liquidityPoolRecipient;
// Owner address
address public ownerNFT;
//Base URI
string private url;
struct ProjectData {
string name;
uint256 projectTokenId;
string methodology;
string region;
string emissionType;
string uri;
address creator;
}
struct RetireData {
uint256 retireTokenId;
address beneficiary;
string retirementMessage;
uint256 timeStamp;
uint256 amount;
}
mapping (uint256 => ProjectData) private _projectData;
mapping (uint256 => RetireData) private _retireData;
modifier onlyOwner(address _sender) {
require(_sender == ownerNFT, "Only the owner can call this function");
_;
}
modifier onlyAdmin (address _sender) {
require(_sender == commissionRecipient, "Only the heir can call this function");
_;
}
constructor(
uint96 _liquidityPercentage, address _liquidityPoolRecipient,
string memory _MyToken, string memory _Symbol, string memory _url, address _ownerNFT
) ERC721(_MyToken, _Symbol) {
commissionPercentage = 100;
liquidityPercentage = _liquidityPercentage;
commissionRecipient = 0xE3506A38C80D8bA1ef219ADF55E31E18FB88EbF4;
liquidityPoolRecipient = _liquidityPoolRecipient;
ownerNFT = _ownerNFT;
_setDefaultRoyalty(commissionRecipient, commissionPercentage);
url = _url;
}
function _baseURI() internal view override returns (string memory) {
return url;
}
function pause(address _sender) external onlyAdmin(_sender) {
_pause();
}
function unpause(address _sender) external onlyAdmin(_sender) {
_unpause();
}
function safeMint(address _to, string memory _uri, string memory _name,
string memory _methodology, string memory _region, string memory _emissionType, address _sender) public whenNotPaused onlyOwner(_sender) {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(_to, tokenId);
_setTokenURI(tokenId, _uri);
// Create a new ProjectData struct and store it in the contract's storage
_projectData[tokenId] = ProjectData({
projectTokenId : tokenId,
uri : _uri,
name : _name,
methodology : _methodology,
region : _region,
emissionType : _emissionType,
creator : _sender
});
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
internal
whenNotPaused
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId, batchSize);
if (from != address(0)) {
address owner = ownerOf(tokenId);
require(owner == msg.sender, "Only the owner of NFT can transfer or burn it");
}
}
function _burn(uint256 tokenId) internal whenNotPaused override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function burnToken(uint256 tokenId, string memory _retirementMessage, uint256 _amount, address _sender) public whenNotPaused onlyOwner(_sender) {
address owner = ownerOf(tokenId);
require(owner == msg.sender, "Only the owner of NFT can burn it");
_burn(tokenId);
// Create a new ProjectData struct and store it in the contract's storage
_retireData[tokenId] = RetireData({
retireTokenId : tokenId,
beneficiary : msg.sender,
retirementMessage : _retirementMessage,
timeStamp : block.timestamp,
amount : _amount
});
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
// The following functions are overrides required by Solidity.
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC2981, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
I'm trying to group everything in a flattened contract to have the complete ABI

DeclarationError: Identifier not found or not unique. --> project:/contracts/"".sol:26:23: | 26 | function initialize() initializer public

When running npx truffle compile, i get the above error message.
I am trying to transition an NFT smart contract into upgradeable form and have imported the relevant source codes. It deploys to testnet fine, but when replacing the constructor with "function Initialize() initializer pubic {" i get the above error message.
Can someone help?
I also get an "Identifier not found or not unique" by my "mapping(address=>bool) private _operatorEnabled;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/access/AccessControl.sol";
contract ERC721CarbonAsset is ERC721URIStorage, Pausable, AccessControl {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
// Base URI
string private _baseUri;
address _forwarder;
mapping(uint256 => string) private _digests;
mapping(uint256 => string) private _infoRoots;
// Addresses under operator control
mapping(address => bool) private _operatorEnabled;
function initialize() initializer public {
// constructor() public ERC721("", "") Pausable() {
_baseUri = "";
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(PAUSER_ROLE, msg.sender);
_setupRole(MINTER_ROLE, msg.sender);
_setupRole(BURNER_ROLE, msg.sender);
_setupRole(OPERATOR_ROLE, msg.sender);
}
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
}
/**
* #dev See {ERC20-_beforeTokenTransfer}.
* Taken from ERC20Pausable
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC721Pausable: token transfer while paused");
}
function mint(address to, uint256 tokenId, string memory tokenUri, string memory digest) public onlyRole(MINTER_ROLE) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenUri);
_digests[tokenId] = digest;
}
function burn(uint256 tokenId) public onlyRole(BURNER_ROLE) {
_burn(tokenId);
}
function setBaseURI(string memory uri) external onlyRole(OPERATOR_ROLE) {
_baseUri = uri;
}
/**
* #dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual override returns (string memory) {
return _baseUri;
}
function infoRoot(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _infoRoot = _infoRoots[tokenId];
// If there is no infoRoot set, return an empty string.
if (bytes(_infoRoot).length == 0) {
return "";
}
return _infoRoot;
}
function setInfoRoot(uint256 tokenId, string memory _infoRoot) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_infoRoots[tokenId] = _infoRoot;
}
function digest(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory digest = _digests[tokenId];
// If there is no digest set, return an empty string.
if (bytes(digest).length == 0) {
return "";
}
return digest;
}
function setDigest(uint256 tokenId, string memory digest) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_digests[tokenId] = digest;
}
// Operator initiatiated token transfer
function operatorTransfer(address recipient, uint256 tokenId) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
address owner = ownerOf(tokenId);
require(isOperatorControlled(owner), "ERC721: sender not under operator control");
// Reset appoval
_approve(msg.sender, tokenId);
transferFrom(owner, recipient, tokenId);
return true;
}
// Address owner can enable their address for operator control
// Default state is operator disabled
function enableOperatorControl() external whenNotPaused() returns (bool) {
require(msgSender() != address(0), "ERC20: owner is a zero address");
require(!isOperatorControlled(msgSender()), "ERC20: owner already under operator control");
_operatorEnabled[msgSender()] = true;
return true;
}
// Operator role can remove operator control from an address
function disableOperatorControl(address owner) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
require(isOperatorControlled(owner), "ERC721: owner not under operator control");
_operatorEnabled[owner] = false;
return true;
}
function isOperatorControlled(address owner) public view returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
return _operatorEnabled[owner];
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, AccessControl) returns (bool) {
return super.supportsInterface(interfaceId);
}
function msgSender() internal view returns(address sender) {
if(msg.sender == _forwarder) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
function setForwarder(address forwarder) external onlyRole(OPERATOR_ROLE) returns (bool) {
_forwarder = forwarder;
return true;
}
function getForwarder() external view returns (address) {
return _forwarder;
}
}
I tried to change the initializer function around a bit, inline with onlyInitializing functionality https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v4.4.1
But that also returned a similar error regarding identifier not found or not unique
There were a few problems with the code:
there needs to be a constructor function that sets the token name and symbol (inherited from ERC721 contract)
the initialize function should not also have the word "initializer" in the function declaration
The code will work if with just the above, but there are warnings regarding the overlapping of your function named "digest" with the name "digest" of various input parameters and variables defined within a few functions. Easiest way to solve this is to change the function name
updated code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/access/AccessControl.sol";
contract ERC721CarbonAsset is ERC721URIStorage, Pausable, AccessControl {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
// Base URI
string private _baseUri;
address _forwarder;
mapping(uint256 => string) private _digests;
mapping(uint256 => string) private _infoRoots;
// Addresses under operator control
mapping(address => bool) private _operatorEnabled;
constructor() ERC721("BasicNFT", "BNFT") {}
function initialize() public {
// constructor() public ERC721("", "") Pausable() {
_baseUri = "";
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(PAUSER_ROLE, msg.sender);
_setupRole(MINTER_ROLE, msg.sender);
_setupRole(BURNER_ROLE, msg.sender);
_setupRole(OPERATOR_ROLE, msg.sender);
}
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
}
/**
* #dev See {ERC20-_beforeTokenTransfer}.
* Taken from ERC20Pausable
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC721Pausable: token transfer while paused");
}
function mint(address to, uint256 tokenId, string memory tokenUri, string memory digest) public onlyRole(MINTER_ROLE) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenUri);
_digests[tokenId] = digest;
}
function burn(uint256 tokenId) public onlyRole(BURNER_ROLE) {
_burn(tokenId);
}
function setBaseURI(string memory uri) external onlyRole(OPERATOR_ROLE) {
_baseUri = uri;
}
/**
* #dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual override returns (string memory) {
return _baseUri;
}
function infoRoot(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _infoRoot = _infoRoots[tokenId];
// If there is no infoRoot set, return an empty string.
if (bytes(_infoRoot).length == 0) {
return "";
}
return _infoRoot;
}
function setInfoRoot(uint256 tokenId, string memory _infoRoot) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_infoRoots[tokenId] = _infoRoot;
}
function digestDifferentName(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory digest = _digests[tokenId];
// If there is no digest set, return an empty string.
if (bytes(digest).length == 0) {
return "";
}
return digest;
}
function setDigest(uint256 tokenId, string memory digest) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_digests[tokenId] = digest;
}
// Operator initiatiated token transfer
function operatorTransfer(address recipient, uint256 tokenId) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
address owner = ownerOf(tokenId);
require(isOperatorControlled(owner), "ERC721: sender not under operator control");
// Reset appoval
_approve(msg.sender, tokenId);
transferFrom(owner, recipient, tokenId);
return true;
}
// Address owner can enable their address for operator control
// Default state is operator disabled
function enableOperatorControl() external whenNotPaused() returns (bool) {
require(msgSender() != address(0), "ERC20: owner is a zero address");
require(!isOperatorControlled(msgSender()), "ERC20: owner already under operator control");
_operatorEnabled[msgSender()] = true;
return true;
}
// Operator role can remove operator control from an address
function disableOperatorControl(address owner) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
require(isOperatorControlled(owner), "ERC721: owner not under operator control");
_operatorEnabled[owner] = false;
return true;
}
function isOperatorControlled(address owner) public view returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
return _operatorEnabled[owner];
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, AccessControl) returns (bool) {
return super.supportsInterface(interfaceId);
}
function msgSender() internal view returns(address sender) {
if(msg.sender == _forwarder) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
function setForwarder(address forwarder) external onlyRole(OPERATOR_ROLE) returns (bool) {
_forwarder = forwarder;
return true;
}
function getForwarder() external view returns (address) {
return _forwarder;
}
}
As a general rule of thumb, upgradeable contracts cannot contain Constructors.
See https://docs.openzeppelin.com/learn/upgrading-smart-contracts
I have added "#openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
and inherited from this in the contract declaration, which now doesn't return the initial error message.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/access/AccessControl.sol";
import "#openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
abstract contract ERC721CarbonAsset is ERC721URIStorage, Pausable, AccessControl, Initializable {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
// Base URI
string private _baseUri;
address _forwarder;
mapping(uint256 => string) private _digests;
mapping(uint256 => string) private _infoRoots;
// Addresses under operator control
mapping(address => bool) private _operatorEnabled;
function initialize() initializer public {
// constructor() public ERC721("", "") Pausable() {
_baseUri = "";
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(PAUSER_ROLE, msg.sender);
_setupRole(MINTER_ROLE, msg.sender);
_setupRole(BURNER_ROLE, msg.sender);
_setupRole(OPERATOR_ROLE, msg.sender);
}
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
}
/**
* #dev See {ERC20-_beforeTokenTransfer}.
* Taken from ERC20Pausable
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC721Pausable: token transfer while paused");
}
function mint(address to, uint256 tokenId, string memory tokenUri, string memory digest) public onlyRole(MINTER_ROLE) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenUri);
_digests[tokenId] = digest;
}
function burn(uint256 tokenId) public onlyRole(BURNER_ROLE) {
_burn(tokenId);
}
function setBaseURI(string memory uri) external onlyRole(OPERATOR_ROLE) {
_baseUri = uri;
}
/**
* #dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual override returns (string memory) {
return _baseUri;
}
function infoRoot(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _infoRoot = _infoRoots[tokenId];
// If there is no infoRoot set, return an empty string.
if (bytes(_infoRoot).length == 0) {
return "";
}
return _infoRoot;
}
function setInfoRoot(uint256 tokenId, string memory _infoRoot) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_infoRoots[tokenId] = _infoRoot;
}
function digest(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory digest = _digests[tokenId];
// If there is no digest set, return an empty string.
if (bytes(digest).length == 0) {
return "";
}
return digest;
}
function setDigest(uint256 tokenId, string memory digest) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_digests[tokenId] = digest;
}
// Operator initiatiated token transfer
function operatorTransfer(address recipient, uint256 tokenId) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
address owner = ownerOf(tokenId);
require(isOperatorControlled(owner), "ERC721: sender not under operator control");
// Reset appoval
_approve(msg.sender, tokenId);
transferFrom(owner, recipient, tokenId);
return true;
}
// Address owner can enable their address for operator control
// Default state is operator disabled
function enableOperatorControl() external whenNotPaused() returns (bool) {
require(msgSender() != address(0), "ERC20: owner is a zero address");
require(!isOperatorControlled(msgSender()), "ERC20: owner already under operator control");
_operatorEnabled[msgSender()] = true;
return true;
}
// Operator role can remove operator control from an address
function disableOperatorControl(address owner) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
require(isOperatorControlled(owner), "ERC721: owner not under operator control");
_operatorEnabled[owner] = false;
return true;
}
function isOperatorControlled(address owner) public view returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
return _operatorEnabled[owner];
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, AccessControl) returns (bool) {
return super.supportsInterface(interfaceId);
}
function msgSender() internal view returns(address sender) {
if(msg.sender == _forwarder) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
function setForwarder(address forwarder) external onlyRole(OPERATOR_ROLE) returns (bool) {
_forwarder = forwarder;
return true;
}
function getForwarder() external view returns (address) {
return _forwarder;
}
}

Need some help resolving smart contract warnings

New solidity programmer here.
I'm trying to create a smart contract where a user can create a Bounty. The creator sets the bounty on the smart contract in the constructor. They can subsequently choose the recipient of the funds after evaluation of some criteria. They can cancel, increase the bounty.
I tested the code out and it appears to work, but I'm getting some warnings in remix IDE that I don't know how to fix.
Could some one show me how its supposed to be done?
contract Bounty {
address payable public owner;
address payable public provider;
uint256 private bounty;
bool isActive;
event IncreaseBounty (uint256 oldBounty, uint256 newBounty);
event Paid(address owner, address payee, uint256 amount);
event Cancel(address owner, uint256 amount);
constructor() payable {
owner = payable(msg.sender);
bounty = msg.value;
isActive = true;
}
function cancel() public {
require(isActive, "contract must be active");
require(owner == msg.sender, "Only the owner can cancel the bounty");
uint256 bountyTemp = bounty;
bounty = 0;
owner.transfer(bountyTemp);
isActive = false;
emit Cancel(msg.sender, bountyTemp);
}
function setAndTransferToProvider(address addy) public {
require(isActive, "contract must be active");
require(owner == msg.sender, "Only the owner release the funds");
provider = payable(addy);
provider.transfer(bounty);
uint256 bountyUsed = bounty;
bounty = 0;
isActive = false;
emit Paid(owner, provider, bountyUsed);
}
function increaseBounty() payable external returns (uint256) {
require(isActive, "contract must be active");
require(owner == msg.sender, "Only the owner can increase the bounty");
uint oldBounty = bounty;
bounty += uint(msg.value);
emit IncreaseBounty(oldBounty, bounty);
return bounty;
}
function getBounty() public view returns (uint256) {
require(isActive, "contract must be active");
return bounty;
}
}
Try to put this line
provider.transfer(bounty);
right before the emit of the events on every function.
You can check this article for more understanding of reentrancy attacks.

Factory error The called function should be payable

I am using the Opensea Creatures repository (https://github.com/ProjectOpenSea/opensea-creatures.git) to make a Factory and create my ERC721 tokens. I have added the function _setTokenURI (newTokenId, metadataURI); in ERC721Tradable.sol to add the URI when doing mint but it gives me the following error:
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
the files involved are these:
CreatureFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "openzeppelin-solidity/contracts/token/ERC721/ERC721.sol";
import "./IFactoryERC721.sol";
import "./Creature.sol";
contract CreatureFactory is FactoryERC721, Ownable {
using Strings for string;
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
address public proxyRegistryAddress;
address public nftAddress;
address public lootBoxNftAddress;
string public baseURI = "https://terrorverso.herokuapp.com/api/token/";
/*
* Enforce the existence of only 100 OpenSea creatures.
*/
uint256 CREATURE_SUPPLY = 100;
/*
* Three different options for minting Creatures (basic, premium, and gold).
*/
uint256 NUM_OPTIONS = 3;
uint256 SINGLE_CREATURE_OPTION = 0;
uint256 MULTIPLE_CREATURE_OPTION = 1;
uint256 LOOTBOX_OPTION = 2;
uint256 NUM_CREATURES_IN_MULTIPLE_CREATURE_OPTION = 4;
constructor(address _proxyRegistryAddress, address _nftAddress) {
proxyRegistryAddress = _proxyRegistryAddress;
nftAddress = _nftAddress;
fireTransferEvents(address(0), owner());
}
function name() override external pure returns (string memory) {
return "Factory";
}
function symbol() override external pure returns (string memory) {
return "FACT";
}
function supportsFactoryInterface() override public pure returns (bool) {
return true;
}
function numOptions() override public view returns (uint256) {
return NUM_OPTIONS;
}
function transferOwnership(address newOwner) override public onlyOwner {
address _prevOwner = owner();
super.transferOwnership(newOwner);
fireTransferEvents(_prevOwner, newOwner);
}
function fireTransferEvents(address _from, address _to) private {
for (uint256 i = 0; i < NUM_OPTIONS; i++) {
emit Transfer(_from, _to, i);
}
}
function mint(uint256 _optionId, address _toAddress, string memory metadataURI) override public {
// Must be sent from the owner proxy or owner.
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
assert( address(proxyRegistry.proxies(owner())) == _msgSender() || owner() == _msgSender() || _msgSender() == lootBoxNftAddress );
require(canMint(_optionId));
Creature openSeaCreature = Creature(nftAddress);
if (_optionId == SINGLE_CREATURE_OPTION) {
openSeaCreature.mintTo(_toAddress,metadataURI);
} else if (_optionId == MULTIPLE_CREATURE_OPTION) {
for (
uint256 i = 0;
i < NUM_CREATURES_IN_MULTIPLE_CREATURE_OPTION;
i++
) {
openSeaCreature.mintTo(_toAddress,metadataURI);
}
}
}
function canMint(uint256 _optionId) override public view returns (bool) {
if (_optionId >= NUM_OPTIONS) {
return false;
}
Creature openSeaCreature = Creature(nftAddress);
uint256 creatureSupply = openSeaCreature.totalSupply();
uint256 numItemsAllocated = 0;
if (_optionId == SINGLE_CREATURE_OPTION) {
numItemsAllocated = 1;
} else if (_optionId == MULTIPLE_CREATURE_OPTION) {
numItemsAllocated = NUM_CREATURES_IN_MULTIPLE_CREATURE_OPTION;
}
return creatureSupply < (CREATURE_SUPPLY - numItemsAllocated);
}
function tokenURI(uint256 _optionId) override external view returns (string memory) {
return string(abi.encodePacked(baseURI, Strings.toString(_optionId)));
}
/**
* Hack to get things to work automatically on OpenSea.
* Use transferFrom so the frontend doesn't have to worry about different method names.
*/
function transferFrom(
address _from,
address _to,
uint256 _tokenId,
string memory metadataURI
) public {
mint(_tokenId, _to, metadataURI);
}
/**
* Hack to get things to work automatically on OpenSea.
* Use isApprovedForAll so the frontend doesn't have to worry about different method names.
*/
function isApprovedForAll(address _owner, address _operator)
public
view
returns (bool)
{
if (owner() == _owner && _owner == _operator) {
return true;
}
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
if (
owner() == _owner &&
address(proxyRegistry.proxies(_owner)) == _operator
) {
return true;
}
return false;
}
/**
* Hack to get things to work automatically on OpenSea.
* Use isApprovedForAll so the frontend doesn't have to worry about different method names.
*/
function ownerOf(uint256 _tokenId) public view returns (address _owner) {
return owner();
}
}
ERC721Tradable.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC721/ERC721.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "./common/meta-transactions/ContentMixin.sol";
import "./common/meta-transactions/NativeMetaTransaction.sol";
contract OwnableDelegateProxy {}
contract ProxyRegistry {
mapping(address => OwnableDelegateProxy) public proxies;
}
/**
* #title ERC721Tradable
* ERC721Tradable - ERC721 contract that whitelists a trading address, and has minting functionality.
*/
abstract contract ERC721Tradable is ContextMixin, ERC721Enumerable, NativeMetaTransaction, Ownable, ERC721URIStorage {
using SafeMath for uint256;
address proxyRegistryAddress;
uint256 private _currentTokenId = 0;
constructor(
string memory _name,
string memory _symbol,
address _proxyRegistryAddress
) ERC721(_name, _symbol) {
proxyRegistryAddress = _proxyRegistryAddress;
_initializeEIP712(_name);
}
/**
* #dev Mints a token to an address with a tokenURI.
* #param _to address of the future owner of the token
*/
function mintTo(address _to, string memory metadataURI) public onlyOwner {
uint256 newTokenId = _getNextTokenId();
_mint(_to, newTokenId);
_setTokenURI(newTokenId, metadataURI);
_incrementTokenId();
}
/**
* #dev calculates the next token ID based on value of _currentTokenId
* #return uint256 for the next token ID
*/
function _getNextTokenId() private view returns (uint256) {
return _currentTokenId.add(1);
}
/**
* #dev increments the value of _currentTokenId
*/
function _incrementTokenId() private {
_currentTokenId++;
}
function baseTokenURI() virtual public pure returns (string memory);
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
internal
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/**
* Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings.
*/
function isApprovedForAll(address owner, address operator)
override
public
view
returns (bool)
{
// Whitelist OpenSea proxy contract for easy trading.
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
if (address(proxyRegistry.proxies(owner)) == operator) {
return true;
}
return super.isApprovedForAll(owner, operator);
}
/**
* This is used instead of msg.sender as transactions won't be sent by the original token owner, but by OpenSea.
*/
function _msgSender()
internal
override
view
returns (address sender)
{
return ContextMixin.msgSender();
}
}
and Creature.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ERC721Tradable.sol";
/**
* #title Creature
* Creature - a contract for my non-fungible creatures.
*/
contract Creature is ERC721Tradable{
constructor(address _proxyRegistryAddress)
ERC721Tradable("ExampleNFT", "EXA", _proxyRegistryAddress)
{}
function baseTokenURI() override public pure returns (string memory) {
return "https://example.com/api/token/";
}
function contractURI() public pure returns (string memory) {
return "https://creatures-api.opensea.io/contract/opensea-creatures";
}
}

How can I multiply dates in Solidity after Safemath.sol library is deprecated

I had this piece of code compiling in Solidity 0.6.0 without errors(I'm using Remix). But suddenly SafeMath library got deprecated because it wasn't necessary to import it anymore and I don't know how to fix this line:
uint raiseUntil = now.add(durationInDays.mul(1 days));
where I calculate a future date using the ¨mul¨ function.
I let you all code below. It's the backend of a crowdfunding platform. The raisedUntil variable is the date where the deadline of the crowdfunding project ends.
pragma solidity 0.6.0;
// Importing OpenZeppelin's SafeMath Implementation
import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol';
contract Crowdfunding {
using SafeMath for uint256;
// List of existing projects
Project[] private projects;
// Event that will be emitted whenever a new project is started
event ProjectStarted(
address contractAddress,
address projectStarter,
string projectTitle,
string projectDesc,
uint256 deadline,
uint256 goalAmount
);
/** #dev Function to start a new project.
* #param title Title of the project to be created
* #param description Brief description about the project
* #param durationInDays Project deadline in days
* #param amountToRaise Project goal in wei
*/
function startProject(
string calldata title,
string calldata description,
uint durationInDays,
uint amountToRaise
) external {
uint raiseUntil = now.add(durationInDays.mul(1 days));
Project newProject = new Project(msg.sender, title, description, raiseUntil, amountToRaise);
projects.push(newProject);
emit ProjectStarted(
address(newProject),
msg.sender,
title,
description,
raiseUntil,
amountToRaise
);
}
/** #dev Function to get all projects' contract addresses.
* #return A list of all projects' contract addreses
*/
function returnAllProjects() external view returns(Project[] memory){
return projects;
}
}
contract Project {
using SafeMath for uint256;
// Data structures
enum State {
Fundraising,
Expired,
Successful
}
// State variables
address payable public creator;
uint public amountGoal; // required to reach at least this much, else everyone gets refund
uint public completeAt;
uint256 public currentBalance;
uint public raiseBy;
string public title;
string public description;
State public state = State.Fundraising; // initialize on create
mapping (address => uint) public contributions;
// Event that will be emitted whenever funding will be received
event FundingReceived(address contributor, uint amount, uint currentTotal);
// Event that will be emitted whenever the project starter has received the funds
event CreatorPaid(address recipient);
// Modifier to check current state
modifier inState(State _state) {
require(state == _state);
_;
}
// Modifier to check if the function caller is the project creator
modifier isCreator() {
require(msg.sender == creator);
_;
}
constructor
(
address payable projectStarter,
string memory projectTitle,
string memory projectDesc,
uint fundRaisingDeadline,
uint goalAmount
) public {
creator = projectStarter;
title = projectTitle;
description = projectDesc;
amountGoal = goalAmount;
raiseBy = fundRaisingDeadline;
currentBalance = 0;
}
/** #dev Function to fund a certain project.
*/
function contribute() external inState(State.Fundraising) payable {
require(msg.sender != creator);
contributions[msg.sender] = contributions[msg.sender].add(msg.value);
currentBalance = currentBalance.add(msg.value);
emit FundingReceived(msg.sender, msg.value, currentBalance);
checkIfFundingCompleteOrExpired();
}
/** #dev Function to change the project state depending on conditions.
*/
function checkIfFundingCompleteOrExpired() public {
if (currentBalance >= amountGoal) {
state = State.Successful;
payOut();
} else if (now > raiseBy) {
state = State.Expired;
}
completeAt = now;
}
/** #dev Function to give the received funds to project starter.
*/
function payOut() internal inState(State.Successful) returns (bool) {
uint256 totalRaised = currentBalance;
currentBalance = 0;
if (creator.send(totalRaised)) {
emit CreatorPaid(creator);
return true;
} else {
currentBalance = totalRaised;
state = State.Successful;
}
return false;
}
/** #dev Function to retrieve donated amount when a project expires.
*/
function getRefund() public inState(State.Expired) returns (bool) {
require(contributions[msg.sender] > 0);
uint amountToRefund = contributions[msg.sender];
contributions[msg.sender] = 0;
if (!msg.sender.send(amountToRefund)) {
contributions[msg.sender] = amountToRefund;
return false;
} else {
currentBalance = currentBalance.sub(amountToRefund);
}
return true;
}
/** #dev Function to get specific information about the project.
* #return Returns all the project's details
*/
function getDetails() public view returns
(
address payable projectStarter,
string memory projectTitle,
string memory projectDesc,
uint256 deadline,
State currentState,
uint256 currentAmount,
uint256 goalAmount
) {
projectStarter = creator;
projectTitle = title;
projectDesc = description;
deadline = raiseBy;
currentState = state;
currentAmount = currentBalance;
goalAmount = amountGoal;
}
}
You might decide to switch to a newer version of Solidity (current is 0.8.4), where now is deprecated so I already used block.timestamp instead. It's the same thing - now was just its alias.
The SafeMath library checks whether an arithmetic operation (such as multiplication or addition) on two unsigned integers would overflow/underflow. If it would, it throws an exception. If it wouldn't, it performs the arithmetic operation. Since Solidity 0.8 this is done automatically and SafeMath is not needed, so another reason to use the current version.
In Solidity 0.8 and newer, if this would overflow, it would throw an exception automatically
uint raiseUntil = block.timestamp + durationInDays * 1 days;
In older versions, you'll need to check for the possible overflow yourself and throw the exception from your code (the same behavior as SafeMath would do).
uint durationInSeconds = durationInDays * 1 days;
// Check that the result of division (inverse operation to multiplication) is the original number.
// If it's not, throw an exception, because the multiplication overflowed.
require(durationInSeconds / durationInDays == 1 days, 'Multiplication overflow');
uint raiseUntil = block.timestamp + durationInSeconds;
// Check that the result of subtraction (inverse operation to addition) is the original number.
// If it's not, throw an exception, because the addition overflowed.
require(raiseUntil - block.timestamp == durationInSeconds, 'Addition overflow');
Integer overflow/underflow is one of the most common security vulnerabilities in smart contracts. If your startProject() function was vulnerable, it would only allow to start a project with a deadline in the past. But in other implementations it can have more serious consequences. For example if an attacker exploits this vulnerability on a token contract, it could allow them to spend more tokens than they own.