I created an ERC-721 contract that has a mint function that is payable. I have used a nonReentrant modifier with it which is found in the Openzeppelin contracts under Renterancy. Does this cause errors?
Does payable invoke the nonreenterant modifier?
The OpenZeppelin nonReentrant modifier (link) prevents the reentrancy attack (link).
But it does not affect the function state mutability (such as payable).
Related
I'm thinking about my smart contract and want to have a secure contract. But I really don't know that internal functions are safe or not.
This is a very BASIC contract that uses OpenZeppelin contracts:
contract MyContract is ERC20 {
constructor () ERC20("test", "test") {
_mint(msg.sender, 1000);
}
}
_mint is an internal function from Openzeppelin ERC20 contract.
Can someone deploy another contract and call the MyContract _mint() function?
If yes, How can we secure it?
The function _mint() from ERC20 is internal.
Internal functions can only be called within the contract or by the contracts inherited from the current one.
That means that no other contract can call MyContract._mint(), you can only call _mint() from inside MyContract.
I want to implement a burn feature in my ERC721 contract in Solidity. To do so, I have imported the function burn from ERC721Burnable.sol.
Since I have imported it I get the following error:
"Derived contract must override function _beforeTokenTransfer".
The same goes with supportsInterface function.
I did override both of them as you can see below. It works but I would like to understand why do I have to do that?
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
I checked Openzeppelin repo, _beforeTokenTransfer is called inside _burn function. At first, I thought it was the main reason but the fact is that _beforeTokenTransfer is also called inside mint and I did not have that error before.
I have no idea why I have to override supportsInterface.
Thanks
ERC721Burnable inherits from two contracts:
abstract contract ERC721Burnable is Context, ERC721 {}
ERC721.sol contract has _beforeTokenTransfer and _afterTokenTransfer unimplemeted functions. you have to implement those in your contract.
from this github issue
ERC721Enumerable and ERC721Burnable both override the
_beforeTokenTransfer and supportsInterface functions. Solidity requires you to "fix" that overriding conflict. If we were able to
address that in our contract we would, but its a solidity requirement
that the child contract explicitly resolves this.
Looks like you 2 of contracts are conflicting inhering supportsInterface
I have been following Solidity, Blockchain, and Smart Contract Course – Beginner to Expert Python Tutorial (https://www.youtube.com/watch?v=M576WGiDBdQ&t=28658s).
At a certain point in the tutorial (around hour 9), the following line of code exists:
weth=interface.IWeth(SomeAddress)
tx=weth.deposit({"from":account, "value": 0.01*10**18})
My understanding is that interfaces get compiled into ABI for use by some external entity.
the IWeth interface is as follows:
pragma solidity ^0.4.19;
/*this is the interface for the WETH contract */
interface IWeth {
function allowance(address owner, address spender)
external
view
returns (uint256 remaining);
function approve(address spender, uint256 value)
external
returns (bool success);
function balanceOf(address owner) external view returns (uint256 balance);
function decimals() external view returns (uint8 decimalPlaces);
function name() external view returns (string memory tokenName);
function symbol() external view returns (string memory tokenSymbol);
function totalSupply() external view returns (uint256 totalTokensIssued);
function transfer(address to, uint256 value)
external
returns (bool success);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool success);
function deposit() external;
function withdraw(uint256 wad) external;
}
The above interface is not implemented anywhere in the project but the project compiles and runs just fine. In my limited understanding of OOP, shouldn't an interface be implemented somewhere? if so, where is it implemented? If not, does the interface ( in this case IWeth) exist for the sole purpose of generating an ABI?
Also, I'm confused about how the interface is used as in weth=interface.IWeth(SomeAddress). In general, how can we write ...InterfaceName(someArg) when it is not even declared in the interface file?
Thanks in advance!
You can use an interface in your contract to call functions in another contract. Interfaces are most useful when you need to add functionality but instead of adding complexity to your application you use it from another contract. They reduce code duplication.
brownie is already loading interfaces. This is from docs
The InterfaceContainer object (available as interface) provides access
to the interfaces within your project’s interfaces/ folder.
interface.IWeth(SomeAddress) this tells Ethereum virtual machine to create a contract instance of given contract address with the functionalities of the interface. And then your app is calling deposit of that contract instance
Why does Remix fail to deploy the simple contract (simplified from the Mastering Ethereum book https://github.com/ethereumbook/ethereumbook/blob/develop/code/Solidity/Faucet2.sol )? --
pragma solidity ^0.4.19;
contract Faucet {
function withdraw(uint withdraw_amount) public {
require(withdraw_amount <= 100000000000000000);
msg.sender.transfer(withdraw_amount);
}
function () external payable {}
}
No matter how I raise gasLimit and/or gasPrice
Your code is fine (I have also tried it myself). From what I see above you are also sending a value along with the deploy. Since you have not defined a constructor yourself the default one is being called which is not payable. If you want to send ether when you deploy the contract you should also define a payable constructor.
I am trying to make a contract that has two different tokens used for different aspects of the contract. I would like both of the tokens to be able to fit ERC20 standards but I am not sure how to specify unique variables and functions for each.
If you consider the structure of an ERC 20 token : https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/Token.sol , you will see that what you are proposing, although possible, would be a little messy. But more importantly it would transform your token contract into a non-ERC20 token.
uint256 public totalSupply; would need to be replaced with either a mapping or a two separate parameters.
The same would be for managing balances, you would need to change the signature of each method to take an additional parameter for specifying the token you want or create specific method for each token within the contract:
function balanceOf(address _owner) constant returns (uint256 balance);
Would need to be either:
function balanceOf(address _owner, uint256 token_id) constant returns (uint256 balance);
or
function balanceOfTokenA(address _owner) constant returns (uint256 balance);
function balanceOfTokenB(address _owner) constant returns (uint256 balance);
But like I said, either implementation would make your token contract a non-ERC20 token.
You would be better off having two contracts, then both would be ERC20 compatible. You could then write a third contract for managing them if your requirements are that they need to be interfaced via a single contract.
These days, ERC1155, a "multi-token" standard, seems like a good choice for contracts needing multiple tokens:
https://github.com/ethereum/EIPs/issues/1155
Simple Summary:
A standard interface for contracts that manage multiple token types. A
single deployed contract may include any combination of fungible
tokens, non-fungible tokens or other configurations (e.g.
semi-fungible tokens).
See also the openzeppelin implementation