I am missing something conceptually about override the _authorizeUpgrade function when composing two contracts. The setting is that I have two contracts, both upgradeable, as follows:
contract ERC721UpgradeableV1 is Initializable, ERC721Upgradeable, ERC721URIStorageUpgradeable, UUPSUpgradeable {
...
constructor() {
_disableInitializers();
}
function initializeERC721UpgradeableV1(string memory _name, string memory _symbol, string memory uri, address witness ) initializer public {
__ERC721_init(_name,_symbol);
__ERC721URIStorage_init();
__UUPSUpgradeable_init();
baseURI = uri;
admin721 = msg.sender;
witness721 = witness;
isPaused = true;
isWhitelistOnly = true;
}
function _authorizeUpgrade(address newImplementation) internal override {
require(msg.sender == admin721 || msg.sender == witness721);
}
....
}
contract PaymentSplitterUpgradeable is Context, ReentrancyGuard, Initializable, UUPSUpgradeable {
...
/**
* #dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
* the matching position in the `shares` array.
*
* All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
* duplicates in `payees`.
*/
function initializePaymentSplitter( address witness_, address[] memory payees, uint256[] memory shares_) payable public initializer {
require(payees.length == shares_.length, "PaymentSplitterUpgradeable: payees and shares length mismatch");
require(payees.length > 0, "PaymentSplitterUpgradeable: no payees");
paymentWitness = witness_;
paymentOwner = msg.sender;
_addPayoutWindow( payees, shares_);
}
function _authorizeUpgrade(address newImplementation) internal override {
require(msg.sender == paymentOwner || msg.sender == paymentWitness);
}
}
Now I am trying to write an upgradeable version of the two contracts via:
contract ERC721PaymentSplitterV1 is
Initializable,
UUPSUpgradeable,
ERC721UpgradeableV1,
PaymentSplitterUpgradeable
{
/**
* #dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, and `PAUSER_ROLE` to the account that
* deploys the contract.
*/
function initializeERC721LumoPaymentSplitter(
string memory _name,
string memory _symbol,
string memory uri,
address witness_,
address[] memory _payees,
uint256[] memory _shares
) initializer public {
initializeERC721UpgradeableV1(_name, _symbol, uri, witness_);
initializePaymentSplitter(witness_, _payees, _shares);
}
function _authorizeUpgrade(address newImplementation)
internal
override
{}
}
And receive a rather severe message about the function _authorizeUpgrade in ERC721PaymentSplitterV1 with:
`TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?
--> contracts/project/ERC721UpgradeableV1.sol:38:5:
|
38 | function _authorizeUpgrade(address newImplementation) internal override {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Overriding function is here:
--> contracts/project/ERC721PaymentSplitter.sol:32:5:
|
32 | function _authorizeUpgrade(address newImplementation)
| ^ (Relevant source part starts here and spans across multiple lines).
TypeError: Trying to override non-`
ote: This contract:
--> #openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:22:1:
|
22 | abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: This contract:
--> contracts/project/ERC721Lumo.sol:10:1:
TypeError: Derived contract must override function "_msgData". Two or more base classes define function with same name and parameter types.
--> contracts/project/ERC721PaymentSplitter.sol:9:1:
Related
I'm trying to compile this contract but it won't work. I know I can point mint and redeem for address, but since I'll get these from compound, how do I point it to make it compile?
// SPDX-License-Identifier: MIT
pragma solidity <0.9.0;
import "#openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol";
import "#openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";
import {OwnableUpgradeable} from "#openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
contract Myvaultis ERC4626Upgradeable, OwnableUpgradeable {
//compound variable to store address
address _cAsset;
function initialize(
IERC20MetadataUpgradeable asset_,
string memory name_,
string memory symbol_
) public initializer {
__MyVault_init(asset_, name_, symbol_);
_cAsset = 0x00000000000000000000000; //put here cAsset address
}
function __MyVault_init(
IERC20MetadataUpgradeable asset_,
string memory name_,
string memory symbol_
) internal onlyInitializing {
__ERC4626_init_unchained(asset_);
__ERC20_init_unchained(name_, symbol_);
__Ownable_init_unchained();
}
function depositCompound(
IERC20MetadataUpgradeable asset_,
address cAsset_,
uint256 _amount
) public onlyOwner returns (uint) {
asset_.approve(cAsset_, _amount);
// Mint cTokens
uint mintResult = cAsset_.mint(_amount);
return mintResult;
}
function withdrawCompound(
uint256 amount,
bool redeemType,
address cAsset_
) public onlyOwner returns (bool) {
uint256 redeemResult;
if (redeemType == true) {
redeemResult = cAsset_.redeem(amount);
} else {
redeemResult = cAsset_.redeemUnderlying(amount);
}
return true;
}
}
The error i'm getting is
TypeError: Member "mint" not found or not visible after argument-dependent lookup in address.
|
38 | uint mintResult = cAsset_.mint(_amount);
| ^^^^^^^^^^^^
Error HH600: Compilation failed
looks like you haven't defined the contract and your trying to access it via the address.
You might have to define the interface then plug in the address.
contract = interface(address)
then you can use contract.functionName(parameters)
from solidity:
contracts/3_Ballot.sol:33:37: TypeError: Named argument does not match function declaration.
Request memory newRequest = Request({
^ (Relevant source part starts here and spans across multiple lines).
I get this error every time. What should i do for the solve it?
pragma solidity ^0.4.17;
contract Campaign {
struct Request {
string description;
uint value;
address recipient;
bool complete;
}
Request[] public requests;
address public manager;
uint public minimumContirbution;
address[] public approvers;
modifier restricted() {
require (msg.sender == manager);
_;
}
function Campaign (uint minimum) public {
manager = msg.sender;
minimumContirbution = minimum;
}
function contribute () public payable {
require(msg.value > minimumContirbution);
approvers.push(msg.sender);
}
function createRequest(string description, uint value, address recipient) restricted public {
Request memory newRequest = Request({
description: description,
value: value,
restricted: restricted,
complete: false
});
requests.push(newRequest);
}
}
You can define the Request struct in this way and push it into requests array:
function createRequest(string description, uint value, address recipient) restricted public {
Request memory newRequest = Request(description, value, recipient, false);
requests.push(newRequest);
}
In this way, you can add the struct into your array and can retrieve with all parameters setted previously.
Because you're are using wrong argument(restricted) inside you Request type
try this:
Request memory newRequest = Request({
descritption: descritpion,
value: value,
recipient: recipient,
complete: false
});
I have this error "TypeError: Return argument type address is not implicitly convertible to expected type (type of first return variable) address payable. --> Driven.sol:233:16: | 233 | return msg.sender; | ^^^^^^^^^^"
for the following function
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
Please help!
Since Solidity 0.8, msg.sender is not payable anymore. You need to cast it to payable first.
function _msgSender() internal view virtual returns (address payable) {
return payable(msg.sender); // added payable
}
Or you can return just address (not payable):
function _msgSender() internal view virtual returns (address) { // removed payable
return msg.sender;
}
I want to override the following inherited function:
function _setBaseURI(string memory baseURI) public override(ERC721Full, ERC721Metadata) {
_baseURI = baseURI;
}
The problem is that it gives me the error Undeclared Identifier with _baseURI.
The variable was implemented private. Is it for that reason that it cannot be overwritten? And if so, why can the function be?
My contract:
pragma solidity ^0.6.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0-beta.0/contracts/token/ERC721/ERC721Full.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0-beta.0/contracts/drafts/Counters.sol";
contract GameItem is ERC721Full {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() ERC721Full("GameItem", "ITM") public {
}
function awardItem(address player, string memory tokenURI) public returns (uint256) {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(player, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
function _setBaseURI(string memory baseURI) public override(ERC721Full, ERC721Metadata) {
_baseURI = baseURI;
}
}
The Heritage
pragma solidity ^0.6.0;
import "../../GSN/Context.sol";
import "./ERC721.sol";
import "./IERC721Metadata.sol";
import "../../introspection/ERC165.sol";
contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
// Token name
string private _name;
// Token symbol
string private _symbol;
// Base URI
string private _baseURI;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/*
* bytes4(keccak256('name()')) == 0x06fdde03
* bytes4(keccak256('symbol()')) == 0x95d89b41
* bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
*
* => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
*/
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
/**
* #dev Constructor function
*/
constructor (string memory name, string memory symbol) public {
_name = name;
_symbol = symbol;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721_METADATA);
}
/**
* #dev Gets the token name.
* #return string representing the token name
*/
function name() external view override returns (string memory) {
return _name;
}
/**
* #dev Gets the token symbol.
* #return string representing the token symbol
*/
function symbol() external view override returns (string memory) {
return _symbol;
}
/**
* #dev Returns the URI for a given token ID. May return an empty string.
*
* If the token's URI is non-empty and a base URI was set (via
* {_setBaseURI}), it will be added to the token ID's URI as a prefix.
*
* Reverts if the token ID does not exist.
*/
function tokenURI(uint256 tokenId) external view override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
// Even if there is a base URI, it is only appended to non-empty token-specific URIs
if (bytes(_tokenURI).length == 0) {
return "";
} else {
// abi.encodePacked is being used to concatenate strings
return string(abi.encodePacked(_baseURI, _tokenURI));
}
}
/**
* #dev Internal function to set the token URI for a given token.
*
* Reverts if the token ID does not exist.
*
* TIP: if all token IDs share a prefix (e.g. if your URIs look like
* `http://api.myproject.com/token/<id>`), use {_setBaseURI} to store
* it and save gas.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* #dev Internal function to set the base URI for all token IDs. It is
* automatically added as a prefix to the value returned in {tokenURI}.
*
* _Available since v2.5.0._
*/
function _setBaseURI(string memory baseURI) internal virtual {
_baseURI = baseURI;
}
/**
* #dev Returns the base URI set via {_setBaseURI}. This will be
* automatically added as a preffix in {tokenURI} to each token's URI, when
* they are non-empty.
*
* _Available since v2.5.0._
*/
function baseURI() external view returns (string memory) {
return _baseURI;
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
if (to == address(0)) { // When burning tokens
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
}
}
It's a visibility issue.
If you want to access the _baseURI property in a derived contract, you need to make it at least internal (it's currently private).
Which also means copying a set of contracts locally so that you can update the ERC721Metadata.sol and import the updated version (and not the remote version) from the other contracts.
The _setBaseURI() function alone can be overridden because it's visible from your contract.
Private functions and state variables are only visible for the contract they are defined in and not in derived contracts.
Cannot access private property in a derived contract.
Source of the quote: https://docs.soliditylang.org/en/v0.8.3/contracts.html#visibility-and-getters
I am creating a dapp to transfer ownership of the contract from one address to another using testrpc. However,I keep encountering this problem. I have tried using sentransaction method to do perform this ownership change.Perhaps I'm calling the exchange in a wrong manner.
Solidity version 0.4.4
web3 "version": "0.20.2"
web3.js:3127 Uncaught Error: VM Exception while processing transaction: invalid opcode
at Object.InvalidResponse (web3.js:3127)
at RequestManager.send (web3.js:6332)
at Eth.send [as sendTransaction] (web3.js:5066)
at SolidityFunction.sendTransaction (web3.js:4122)
at SolidityFunction.execute (web3.js:4208)
at transferOwnership (luxcure_manu.html:309)
at HTMLButtonElement.onclick (luxcure_manu.html:378
Full solidity contract as of yet.
pragma solidity ^0.4.4;
// TODO: Hash of the cert through IPFS Hash
// Transfer ownership of smart contract
contract LuxSecure {
address public contract_owner; //Manufacturer/owner
//string public current_owner; //Current Owner of good
bytes32 public model; //Model
mapping(uint => address) public owners; //list of owners
uint256 public owners_count;
bytes32 public status; // (Public(Owned by no one), Private(Bought by another entity),stolen(Stolen from public or private))
bytes32 public date_manufactured; //Time
// Set manufacturer of the Good RUN ONCE ONLY
function manufacturer() public{
if(owners_count == 0){
contract_owner = msg.sender;
}
}
//Modifier that only allows owner of the bag to Smart Contract AKA Good to use the function
modifier onlyOwner(){
require(msg.sender == contract_owner);
_;
}
// Add a new product to the blockchain with a new serial
function addNewGoods(bytes32 _model,bytes32 _status, bytes32 _date_manufactured) public returns(bool made) {//Declare Goods struct
setOwner(msg.sender);
model = _model;
status = _status;
date_manufactured = _date_manufactured;
return true;
}
//This function transfer ownership of contract from one entity to another
function transferOwnership(address _newOwner) public onlyOwner(){
require(_newOwner != address(0));
contract_owner = _newOwner;
}
//Set the KEY to uint256 and VALUE owner Ethereum Address
function setOwner(address owner)public{
owners_count += 1 ;
owners[owners_count] = owner;
}
//Get the previous owner in the mappings
function previousOwner()constant public returns(address){
if(owners_count != 0){
uint256 previous_owner = owners_count - 1;
return owners[previous_owner];
}
}
// Getter Methods
function getManufacturer() constant public returns(address){
return contract_owner;
}
function getCurrentOwner() constant public returns(address){
return owners[owners_count] ;
}
function getOwnerCount() constant public returns(uint256){
return owners_count;
}
function getModel() constant public returns(bytes32){
return model;
}
function getStatus() constant public returns(bytes32){
return status;
}
function getDateManufactured() constant public returns(bytes32){
return date_manufactured;
}
}// end of LuxSecure
Javascript to perform the transfer of ownership
function transferOwnership(){
var account_to_transfer = document.getElementById("ethereumaddress").value;
contract.transferOwnership(account_to_transfer,{
from:web3.eth.accounts[0],
gas:4000000
});
}
I don't see any particular mistake in your code. Maybe a bad formatting on the front-side, but can't guess for sure as we have partial front here.
I don't know if it will be some help but sometimes, using truffle, it happened to me to have some functions that returned bad opcode from testrpc/ganache-cli while no apparent error was in the code.
Deleting the ABI, recompiling the smart-contracts to get a brand new ABI and then redeploying the contracts solved the problem.