Can not set opensea.io royalties on a NFT Contract - ethereum

I have the following ERC721 contract which is creating an NFT Collection with specified royalty fees:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "./openzeppelin-contracts/contracts/token/common/ERC2981.sol";
import "./openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
import "./openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "./openzeppelin-contracts/contracts/access/Ownable.sol";
contract Collection is ERC721, ERC721Enumerable, ERC2981, Ownable {
constructor(uint96 _royaltyFeesInBips) ERC721("MyToken", "MTK") {
setRoyaltyInfo(owner(), _royaltyFeesInBips);
}
function safeMint(address to, uint256 tokenId) public onlyOwner {
_safeMint(to, tokenId);
}
function setRoyaltyInfo(address _receiver, uint96 _royaltyFeesInBips) public onlyOwner {
_setDefaultRoyalty(_receiver, _royaltyFeesInBips);
}
function contractURI() public view returns (string memory) {
return "ipfs://QmQRTsxyt8Wv9v9DSLegJNbZqBMPJxb1X3Ueu9QngRFX8g";
}
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, ERC2981)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
with the following contract metadata at contractURI
{
"name": "OpenSea Creatures",
"description": "OpenSea Creatures are adorable aquatic beings primarily for demonstrating what can be done using the OpenSea platform. Adopt one today to try out all the OpenSea buying, selling, and bidding feature set.",
"image": "https://openseacreatures.io/image.png",
"external_link": "https://openseacreatures.io",
"seller_fee_basis_points": 100, # Indicates a 1% seller fee.
"fee_recipient": "0x4c39afBBa8C472F6aB272AC37bA683AE0323dfd7" # Where seller fees will be paid to.
}
unfortunately, when I deploy and check its settings at opensea.io I see that the royalty fees are not automatically set

You can only add royalties via the OpenSea UI.
Go to your collection, hit “edit”, and scroll down to find the royalty section.

I was running into the same issue, judging by what they say in the documentation, they seem to send the revenue in bulk once a month. But i haven’t been able to confirm that yet.
Receiving your revenue
Revenue will be distributed in bulk once a month to the payment address specified.
OpenSea provides it's marketplace infrastructure for free—it's entirely free to get started setting up a marketplace and using our platform. As compensation for this service, 2.5% of each sale will go to OpenSea — independent of whatever fees you choose to receive.
https://docs.opensea.io/docs/10-setting-fees-on-secondary-sales

Related

Best plan of attack for digital certificates for proof of completion on EVM

I am looking to explore the option of creating a digital certificate (as in proof) when someone has completed a portion of training, and for this to be issued on an EVM-compatible blockchain using Solidity.
I have prototyped using ERC721 NFTs to encode a "certificate" however, I'd like to prevent recipients from being able to transfer these certificates. To prevent transfer, I attempted to use the Pause.sol functionality from OpenZeppelin, however, this would result in the entire contract being paused, as opposed to a specific tokenId.
Does anyone have any recommendation on an approach? Am I overcomplicating it if I don't want recipients to be able to trade the certificates (i.e. for them to remain static)? Any pointers would be much appreciated!
The simplest and most raw solution is to just set a mapping value.
pragma solidity ^0.8;
contract TrainingResults {
enum Stage {
NONE,
STAGE_1,
STAGE_2,
COMPLETED
}
mapping (address => Stage) public participantStage;
function setParticipantStage(address _graduate, Stage _stage) external {
require(msg.sender == address(0x123), "Not authorized");
participantStage[_graduate] = _stage;
}
}
Or if you want them to be able to see some kind of NFT in their wallet (that supports NFTs), you can modify the ERC-721 contract to disallow transfers.
For example the OpenZeppelin implementation uses a function named _beforeTokenTransfer() (GitHub link) that can be overwritten to disallow transfers altogether.
pragma solidity ^0.8;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
contract TrainingResults is ERC721 {
constructor() ERC721("TrainingResults", "TR") {}
function _beforeTokenTransfer(address from,address to, uint256 tokenId) override internal {
// Allow only for the admin
// as this function is called on token mint as well
require(msg.sender == address(0x123), "Cannot transfer tokens");
}
}

How to transfer an ERC721 token

I'm trying to transfer an ERC721 token, but I'm getting the error ERC721: transfer caller is not owner nor approved for the transferToken method.
Main.sol
import "./ERC721.sol";
import "./Counters.sol";
contract Main is ERC721 {
using Counters for Counters.Counter;
Counters.Counter internal _tokenIds;
address payable internal admin;
constructor() ERC721("MyToken", "TOKEN") {
admin = payable(msg.sender);
}
}
Auction.sol
import "./Main.sol";
contract Auction is Main {
struct AuctionInfo {
uint256 tokenId;
address highestBidder;
uint highestBid;
}
mapping(string => AuctionInfo) private _auctionInfo;
function createAuction(string memory id) public {
_tokenIds.increment();
uint256 newTokenId = _tokenIds.current();
_mint(msg.sender, newTokenId);
_auctionInfo[id].tokenId = newTokenId;
}
function transferToken(string memory id) public {
require(msg.sender == _auctionInfo[id].highestBidder, "You are not the highest bidder");
safeTransferFrom(address(this), _auctionInfo[id].highestBidder, _auctionInfo[id].tokenId);
}
// other methods...
}
The minting contract is this and the owner of the token is the msg.sender of the minting method if I'm not mistaken. Am I to use the approve (or setApprovalForAll) for this each time before transferring? I've tried this, payable(this), and address(this) for the safeTransferFrom method, but none seem to be working.
For example, I tried the following, but get the same revert message:
approve(address(this), _auctionInfo[id].tokenId);
this.safeTransferFrom(address(this), _auctionInfo[id].highestBidder, _auctionInfo[id].tokenId);
The main principle behind any Blockchain is that nobody on the blockchain network should be trusted, and still the transactions should happen fool proof, with no possibility of any cheating being done (barring of course of some hacking).
If you invoke the approve method from the Auction contract, then the msg.sender for the approve function in the ERC721 token contract is your auction contract address. So, in other words, your Auction Contract is trying to approve itself to sell someone else's NFTs, which is not very trustworthy.
What should really happen is that owner of the NFT should invoke the approve method of the ERC721 contract - i.e. the transaction that you send for the approve function call, should be signed by the NFT owner wallet address. This way, the msg.sender for the approve function in the ERC721 contract will be the owner of the NFT. As per the ERC721 standards, the owner of the NFT can approve anyone they want, to sell their NFT(s), as the no-trust in the network is still maintained (At least I should be able to trust myself). The approve method should be invoked from within your DAPP, before the transferToken function is invoked from the DAPP.
Hope that explains why you are unable to transfer your ERC721 tokens.
Because of the internal visibility of the ERC721._approve() function, you can effectively perform the approval for the user.
Then you'll be able to execute the safeTransferFrom(tokenOwner, receiver, tokenId) from your contract, because your contract address is approved to operate this specific token even though it belongs to the tokenOwner.
This snippet mints the token, assigning the ownership to the msg.sender. But then it also calls the _approve() function that doesn't contain any validations and simply assigns the approval of the token to the Auction address.
pragma solidity ^0.8;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
contract Auction is ERC721 {
constructor() ERC721("CollectionName", "Symbol") {}
function createAuction() public {
uint256 newTokenId = 1;
_mint(msg.sender, newTokenId);
_approve(address(this), newTokenId);
}
}
You can see from the screenshot that the owner is 0x5B... (the user address) and that the token is approved for 0xd9... (the contract address).
Note: The _approve() function is internal - it can be called from the ERC721 contract and contracts deriving from it (in your case Main and Auction), but it can't be called from external contracts or end user addresses.

Fetch pair price from Uniswap using smart contract function

I am relatively new to Solidity, I am trying to fetch the price of a pair with the following contract:
contract Uniswap {
constructor () public payable {
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
// calculate price based on pair reserves
function getTokenPrice(address pairAddress, uint amount) public payable returns(uint)
{
IUniswapV2Pair pair = IUniswapV2Pair(pairAddress);
IERC20 token1 = IERC20(pair.token1());
(uint Res0, uint Res1,) = pair.getReserves();
// decimals
uint res0 = Res0*(10**token1.decimals());
return((amount*res0)/Res1); // return amount of token0 needed to buy token1
}
}
but when I try to run on Remix the getTokenPriceit returns me the following error message:
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.
Any idea why? I am trying to fetch the price of ETH/USDT so the using this website (https://v2.info.uniswap.org/pair/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852) and with the pair address at the end of the URL. Thanks for the help!
When you deploy a contract in Remix, it deploys to a local network. (By default. You can change it and deploy to mainnet as well, if you inject a production Infura provider for example.)
The Uniswap pair contract 0x0d4a11... does not exist on the local network.
The easiest solution is to deploy your contract on the mainnet (where the 0x0d4a11... Uniswap pair contract exists).
Or you can find another Uniswap pair on a public testnet (well-known are Rinkeby, Ropsten, Goerli, and Kovan), and deploy your contract on the same testnet. Don't forget to change the testnet address of the uniswap pair that you pass to your getTokenPrice() function.
Or you can deploy the Uniswap pair contract and all of its dependencies and change the dependencies addreses (which is a lot of work - my guess is that it's dependend on the Uniswap router contract, the actual token contracts of the pair, maybe they are dependend on some other contract, ...) to your local network. From here it's the same - deploy your contract to the local network, and call the getTokenPrice() with the correct pair address.
You may also invoke uniswap's Subgraph using javascript

Is my Solidity code correct and safe to use

I am very new using Solidity to create Ethereum contracts and would like to know if the contract I have created is first correct and safe to use.
What I am doing in this contract is allowing the user to send some ETH from their wallet to a friends wallet but also take a $0.05 fee (194740000000000 wei at time of writing) for using my services.
Now when testing the contract using remix all works fine, but as I am new to solidity contracts I just wanted to get some expert opinions to make sure I am doing everything correctly and safety.
My contract code is:
pragma solidity ^0.5.1;
contract Forwarder {
address payable public receiversAddress = 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C;
address payable public feeAddress = 0xdD870fA1b7C4700F2BD7f44238821C26f7392148;
constructor() payable public {
uint amountToSendReceiver = msg.value-194740000000000;
receiversAddress.transfer(amountToSendReceiver);
feeAddress.transfer(194740000000000);
}
}
As mentioned everything works fine in remix, but is my contract code correct and safe to use? There is no way to use the contract after to maybe steal funds or have any vulnerabilities?
Yes, your code is pretty safe. The only thing I would like to add is line with require condition for code maintainability
And if your vars are not changeable, its better to use constant to make your contract cheaper for deploy ;)
Functions can be declared constant in which case they promise not to
modify the state.
pragma solidity ^0.5.1;
contract Forwarder {
address payable public constant receiversAddress = 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C;
address payable public constant feeAddress = 0xdD870fA1b7C4700F2BD7f44238821C26f7392148;
uint256 constant feeAmount = 194740000000000;
constructor() payable public {
require(msg.value >= feeAmount); // for maintainability, your tx will be reverted anyway, just to show why
feeAddress.transfer(feeAmount); // transfer fee
receiversAddress.transfer(address(this).balance); // transfer remaining amount of msg.value
}
}

How ERC20 tokens control access to their functions?

Here is my question (basically, I want to know if I am right or mistaken):
First of all, we have standard ERC20:
contract ERC20Interface
{
function transfer(address _to, uint _value) public returns (bool success);
function transferFrom(address _from, address _to, uint _value) public returns (bool success);
function approve(address _spender, uint _value) public returns (bool success);
.....
}
Then, in a CrowdSale, we have a token, derived from it:
contract ICO is Ownable {
...
MyToken public m_token;
...
function ICO() public {
m_token = new MyToken();
...
Then the crowdsale ends. The token with list of all people (addresses) that bought it becomes "free" of crowd sale contract:
function finish() onlyOwner public {
if(goalReached()) {
m_token.transferOwnership(m_addrOwner);
My questions:
1. For this token to be traded on exchanges, I have to somehow provide these exchanges with token's address. Where should I get it?
2. Am I correct? Is it how it supposed to work?
In other words, if a token is a separate contract, passed to ICO contract by address, I can see how exchanges can trade it after the end of crowd sale: they have that same address.
But I see a lot of crowdsales on Etherscan, that create contract internally (like in code snippets above). How do I make it "tradable" after the end of a crowd sale in this case?
Thanks.
Most exchanges will only support your token if they see value in it. You'd have to contact the exchanges and they will evaluate if it's worth it to them based on the demand for your token. Even then, they will most likely ask for payment up front before listing.
For example, Bittrex has their submission process documented here. They offer free listing once you pass their verification process (along with some non-free services). Other exchanges follow a similar process.
The contract address you're looking for that you'd have to provide is returned to your client when you deploy your token contract. If you somehow lose the address in your client, you can find it on etherscan.io by searching for the token name/symbol (assuming your token contract follows the ERC20 spec) or by transaction hash. You can also retrieve the address in code:
function getTokenAddress() constant returns (address) {
return address(m_token);
}
Outside of an exchange, you can also do private transfers of tokens by simply adding the token contract address to a wallet like Mist or Parity and sending tokens between addresses.
Note that all of this is independent of the crowd sale. The crowd sale is a separate contract that is used to raise money and do the initial token distribution.