I'm new to dydx flashloans and im builidng a flashloan that should borrow 1INCH tokens but when i tested it on remix it gave an error saying that the token wasnt supported. Is my code wrong or i just cant borrow 1INCH tokens from dydx.
import "#uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
interface Structs {
struct Val {
uint256 value;
}
enum ActionType {
Deposit, // supply tokens
Withdraw, // borrow tokens
Transfer, // transfer balance between accounts
Buy, // buy an amount of some token (externally)
Sell, // sell an amount of some token (externally)
Trade, // trade tokens against another account
Liquidate, // liquidate an undercollateralized or expiring account
Vaporize, // use excess tokens to zero-out a completely negative account
Call // send arbitrary data to an address
}
enum AssetDenomination {
Wei // the amount is denominated in wei
}
enum AssetReference {
Delta // the amount is given as a delta from the current value
}
struct AssetAmount {
bool sign; // true if positive
AssetDenomination denomination;
AssetReference ref;
uint256 value;
}
struct ActionArgs {
ActionType actionType;
uint256 accountId;
AssetAmount amount;
uint256 primaryMarketId;
uint256 secondaryMarketId;
address otherAddress;
uint256 otherAccountId;
bytes data;
}
struct Info {
address owner; // The address that owns the account
uint256 number; // A nonce that allows a single address to control many accounts
}
struct Wei {
bool sign; // true if positive
uint256 value;
}
}
abstract contract DyDxPool is Structs {
function getAccountWei(Info memory account, uint256 marketId)
public
view
virtual
returns (Wei memory);
function operate(Info[] memory, ActionArgs[] memory) public virtual;
}
contract DyDxFlashLoan is Structs {
DyDxPool pool = DyDxPool(0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e);
address public WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
mapping(address => uint256) public currencies;
constructor() {
currencies[WETH] = 1;
}
modifier onlyPool() {
require(
msg.sender == address(pool),
"FlashLoan: could be called by DyDx pool only"
);
_;
}
function tokenToMarketId(address token) public view returns (uint256) {
uint256 marketId = currencies[token];
require(marketId != 0, "FlashLoan: Unsupported token");
return marketId - 1;
}
// the DyDx will call `callFunction(address sender, Info memory accountInfo, bytes memory data) public` after during `operate` call
function flashloan(
address token,
uint256 amount,
bytes memory data
) internal {
IERC20(token).approve(address(pool), amount + 1);
Info[] memory infos = new Info[](1);
ActionArgs[] memory args = new ActionArgs[](3);
infos[0] = Info(address(this), 0);
AssetAmount memory wamt = AssetAmount(
false,
AssetDenomination.Wei,
AssetReference.Delta,
amount
);
ActionArgs memory withdraw;
withdraw.actionType = ActionType.Withdraw;
withdraw.accountId = 0;
withdraw.amount = wamt;
withdraw.primaryMarketId = tokenToMarketId(token);
withdraw.otherAddress = address(this);
args[0] = withdraw;
ActionArgs memory call;
call.actionType = ActionType.Call;
call.accountId = 0;
call.otherAddress = address(this);
call.data = data;
args[1] = call;
ActionArgs memory deposit;
AssetAmount memory damt = AssetAmount(
true,
AssetDenomination.Wei,
AssetReference.Delta,
amount + 1
);
deposit.actionType = ActionType.Deposit;
deposit.accountId = 0;
deposit.amount = damt;
deposit.primaryMarketId = tokenToMarketId(token);
deposit.otherAddress = address(this);
args[2] = deposit;
pool.operate(infos, args);
}
}
contract Arbitrage is DyDxFlashLoan {
IUniswapV2Router02 immutable uRouter;
IUniswapV2Router02 immutable sRouter;
address public owner;
constructor(address _uRouter, address _sRouter) {
uRouter = IUniswapV2Router02(_uRouter);
sRouter = IUniswapV2Router02(_sRouter);
owner = msg.sender;
}
function executeTrade(
address _tokenA,
uint _tokensFromFlashLoan,
address _tokenB,
bool _startOnUniswap
) external {
uint balanceBefore = IERC20(_tokenA).balanceOf(address(this));
bytes memory data = abi.encode(
_startOnUniswap,
_tokenA,
_tokenB,
_tokensFromFlashLoan,
balanceBefore
);
flashloan(_tokenA, _tokensFromFlashLoan, data);
}
function callFunction(
address,
Info calldata,
bytes calldata data
) external onlyPool {
(
bool _startOnUniswap,
address _tokenA,
address _tokenB,
uint256 _tokensFromFlashLoan,
uint256 balanceBefore
) = abi.decode(data, (bool, address, address, uint256, uint256));
uint balanceAfter = IERC20(_tokenA).balanceOf(address(this));
require(
balanceAfter - balanceBefore == _tokensFromFlashLoan,
"didnt receive flash loan"
);
address[] memory tokens;
if (_startOnUniswap == true) {
tokens[0] = _tokenA;
tokens[1] = _tokenB;
swapOnUniswap(_tokensFromFlashLoan, 0, tokens);
tokens[0] = _tokenB;
tokens[1] = _tokenA;
swapOnSushiswap(
IERC20(tokens[0]).balanceOf(address(this)),
0,
tokens
);
} else {
tokens[0] = _tokenA;
tokens[1] = _tokenB;
swapOnSushiswap(_tokensFromFlashLoan, 0, tokens);
tokens[0] = _tokenB;
tokens[1] = _tokenA;
swapOnUniswap(
IERC20(tokens[0]).balanceOf(address(this)),
0,
tokens
);
}
}
function swapOnUniswap(
uint _amountIn,
uint _amountOut,
address[] memory _path
) internal {
require(
IERC20(_path[0]).approve(address(uRouter), _amountIn),
"Uniswap failed the approval"
);
uRouter.swapExactTokensForTokens(
_amountIn,
_amountOut,
_path,
address(this),
(block.timestamp + 1200)
);
}
function swapOnSushiswap(
uint _amountIn,
uint _amountOut,
address[] memory _path
) internal {
require(
IERC20(_path[0]).approve(address(sRouter), _amountIn),
"Sushiswap failed the approval"
);
uRouter.swapExactTokensForTokens(
_amountIn,
_amountOut,
_path,
address(this),
(block.timestamp + 1200)
);
}
}```
I tried to look at dydx docs but i didnt find nothing that could help me
Related
function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
address feeTo = IUniswapV2Factory(factory).feeTo();
feeOn = feeTo != address(0);
uint _kLast = kLast; // gas savings
if (feeOn) {
if (_kLast != 0) {
uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
uint rootKLast = Math.sqrt(_kLast);
if (rootK > rootKLast) {
uint numerator = totalSupply.mul(rootK.sub(rootKLast));
uint denominator = rootK.mul(5).add(rootKLast);
uint liquidity = numerator / denominator;
if (liquidity > 0) _mint(feeTo, liquidity);
}
}
} else if (_kLast != 0) {
kLast = 0;
}
}
// this low-level function should be called from a contract which performs important safety checks
function mint(address to) external lock returns (uint liquidity) {
(uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
uint balance0 = IERC20(token0).balanceOf(address(this));
uint balance1 = IERC20(token1).balanceOf(address(this));
uint amount0 = balance0.sub(_reserve0);
uint amount1 = balance1.sub(_reserve1);
bool feeOn = _mintFee(_reserve0, _reserve1);
uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
if (_totalSupply == 0) {
liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
} else {
liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
}
require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
_mint(to, liquidity);
_update(balance0, balance1, _reserve0, _reserve1);
if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
emit Mint(msg.sender, amount0, amount1);
}
I've start to reading uniV2 codes and i faced this problem, imagine the feeTo has been set in factory contract, and the new pair has been created, for the first time we deposit the amount to the pair contract, now the feeOn is true and kLast is zero that mean
if (feeOn) {
if (_kLast != 0) {
this condition doesn't meet, so my question is for the first time that we create a pair and feeOn is true, Does protocol take its fee?
I've tried to test it, but the protocol didn't take its portion Lp tokens at the first addLiquidity.
I am practising this tutorial in Remix IDE - https://www.youtube.com/watch?v=_aXumgdpnPU
I saw in the Chainlink documentation that their Randomness VRF code has been changed since the development of the video.
I started replacing the parts and trying to deploy the class via Remix but it gives an error which I am not sure how to fix.
Would you be able to check what I have as code and I'll send a screenshot of the error?
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
import "#chainlink/contracts/src/v0.8/ConfirmedOwner.sol";
import "#chainlink/contracts/src/v0.8/VRFV2WrapperConsumerBase.sol";
contract Lottery is
VRFV2WrapperConsumerBase,
ConfirmedOwner
{
address public owner;
address payable[] public players;
uint public lotteryId;
mapping (uint => address payable) public lotteryHistory;
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(
uint256 requestId,
uint256[] randomWords,
uint256 payment
);
struct RequestStatus {
uint256 paid; // amount paid in link
bool fulfilled; // whether the request has been successfully fulfilled
uint256[] randomWords;
}
mapping(uint256 => RequestStatus)
public s_requests; /* requestId --> requestStatus */
// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. Test and adjust
// this limit based on the network that you select, the size of the request,
// and the processing of the callback request in the fulfillRandomWords()
// function.
uint32 callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 requestConfirmations = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFV2Wrapper.getConfig().maxNumWords.
uint32 numWords = 2;
// Address LINK - hardcoded for Goerli
address linkAddress = 0x326C977E6efc84E512bB9C30f76E30c160eD06FB;
// address WRAPPER - hardcoded for Goerli
address wrapperAddress = 0x708701a1DfF4f478de54383E49a627eD4852C816;
constructor()
ConfirmedOwner(msg.sender)
VRFV2WrapperConsumerBase(linkAddress, wrapperAddress)
{
owner = msg.sender;
lotteryId = 1;
}
function requestRandomWords()
external
onlyOwner
returns (uint256 requestId)
{
requestId = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords
);
s_requests[requestId] = RequestStatus({
paid: VRF_V2_WRAPPER.calculateRequestPrice(callbackGasLimit),
randomWords: new uint256[](0),
fulfilled: false
});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] memory _randomWords
) internal override {
require(s_requests[_requestId].paid > 0, "request not found");
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
emit RequestFulfilled(
_requestId,
_randomWords,
s_requests[_requestId].paid
);
payWinner();
}
function getRequestStatus(
uint256 _requestId
)
external
view
returns (uint256 paid, bool fulfilled, uint256[] memory randomWords)
{
require(s_requests[_requestId].paid > 0, "request not found");
RequestStatus memory request = s_requests[_requestId];
return (request.paid, request.fulfilled, request.randomWords);
}
/**
* Allow withdraw of Link tokens from the contract
*/
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(linkAddress);
require(
link.transfer(msg.sender, link.balanceOf(address(this))),
"Unable to transfer"
);
}
function getWinnerByLottery(uint lottery) public view returns (address payable) {
return lotteryHistory[lottery];
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
function getPlayers() public view returns (address payable[] memory) {
return players;
}
function enter() public payable {
require(msg.value > .01 ether);
// address of player entering lottery
players.push(payable(msg.sender));
}
//function getRandomNumber() public view returns (uint) {
//return uint(keccak256(abi.encodePacked(owner, block.timestamp)));
//}
function pickWinner() public onlyowner {
requestRandomWords;
}
function payWinner() public {
uint index = lastRequestId % players.length;
players[index].transfer(address(this).balance);
lotteryHistory[lotteryId] = players[index];
lotteryId++;
// reset the state of the contract
players = new address payable[](0);
}
modifier onlyowner() {
require(msg.sender == owner);
_;
}
}
enter image description here
I am working on dapp using hardhat and goerli testnet and when I run it using npx hardhat run scripts/deploy.js --network goerli, I receive this error, I do have goerli faucet eth on my wallet but still it will display that my account balance is 0:
Error: insufficient funds for intrinsic transaction cost [ See: https://links.ethers.org/v5-errors-INSUFFICIENT_FUNDS ] (error={"name":"ProviderError","_stack":"ProviderError: HttpProviderError\n at HttpProvider.request (C:\\Users\\SAIFUL\\RTW3-Week7-NFT-Marketplace\\node_modules\\hardhat\\src\\internal\\core\\providers\\http.ts:78:19)\n at LocalAccountsProvider.request (C:\\Users\\SAIFUL\\RTW3-Week7-NFT-Marketplace\\node_modules\\hardhat\\src\\internal\\core\\providers\\accounts.ts:181:36)\n at processTicksAndRejections (internal/process/task_queues.js:95:5)\n at EthersProviderWrapper.send (C:\\Users\\SAIFUL\\RTW3-Week7-NFT-Marketplace\\node_modules\\#nomiclabs\\hardhat-ethers\\src\\internal\\ethers-provider-wrapper.ts:13:20)","code":-32000,"_isProviderError":true}, method="sendTransaction", transaction=undefined, code=INSUFFICIENT_FUNDS, version=providers/5.7.2)
at Logger.makeError (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#ethersproject\logger\src.ts\index.ts:269:28)
at Logger.throwError (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#ethersproject\logger\src.ts\index.ts:281:20)
at checkError (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#ethersproject\providers\src.ts\json-rpc-provider.ts:98:16)
at C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#ethersproject\providers\src.ts\json-rpc-provider.ts:265:24
at processTicksAndRejections (internal/process/task_queues.js:95:5) {
reason: 'insufficient funds for intrinsic transaction cost',
code: 'INSUFFICIENT_FUNDS',
error: ProviderError: HttpProviderError
at HttpProvider.request (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\hardhat\src\internal\core\providers\http.ts:78:19)
at LocalAccountsProvider.request (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\hardhat\src\internal\core\providers\accounts.ts:181:36)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at EthersProviderWrapper.send (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#nomiclabs\hardhat-ethers\src\internal\ethers-provider-wrapper.ts:13:20),
method: 'sendTransaction',
transaction: undefined
}
here is my deploy.js file everything is supposed to fine and working but error won't disappear
require("#nomiclabs/hardhat-waffle");
require("#nomiclabs/hardhat-ethers");
const fs = require('fs');
// const infuraId = fs.readFileSync(".infuraid").toString().trim() || "";
task("accounts", "Prints the list of accounts", async(taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
module.exports = {
defaultNetwork: "hardhat",
networks: {
hardhat: {
chainId: 1337
},
goerli: {
url: "https://eth-mainnet.g.alchemy.com/v2/2Hmp7mz6XEpw6Z47cCZx2vEIAYXFGYOL",
accounts: ["private key here"]
}
},
solidity: {
version: "0.8.4",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
}
};
here is my solidity contract:
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "hardhat/console.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
contract NFTMarketplace is ERC721URIStorage {
address payable owner;
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
Counters.Counter private _itemsSold;
uint256 listPrice = 0.01 ether;
constructor() ERC721("NFTMarketplace", "NFTM") {
owner = payable(msg.sender);
}
struct ListedToken {
uint256 tokenId;
address payable owner;
address payable seller;
uint256 price;
bool currentlyListed;
}
mapping(uint256 => ListedToken) private idToListedToken;
function updateListPrice(uint256 _listprice) public payable {
require(owner == msg.sender, "only owner can update listing price ");
listPrice = _listprice;
}
function getListPrice() public view returns (uint256) {
return listPrice;
}
function getLatestIdToListedtoken()
public
view
returns (ListedToken memory)
{
uint256 currentTokenId = _tokenIds.current();
return idToListedToken[currentTokenId];
}
function getListedForToken(uint256 tokenId) public view returns (ListedToken memory) {
return idToListedToken[tokenId];
}
function getCurrentToken() public view returns (uint256) {
return _tokenIds.current();
}
function createToken(string memory tokenURI, uint256 price) public payable returns (uint) {
require(msg.value == listPrice, "Send enough ether to list");
require(price > 0, "Make sure the price isn't negative");
_tokenIds.increment();
uint256 currentTokenId = _tokenIds.current();
_safeMint(msg.sender, currentTokenId);
_setTokenURI(currentTokenId, tokenURI);
createListedToken(currentTokenId, price);
return currentTokenId;
}
function createListedToken(uint256 tokenId, uint256 price) private {
idToListedToken[tokenId] = ListedToken(
tokenId,
payable(address(this)),
payable(msg.sender),
price,
true
);
_transfer(msg.sender, address(this), tokenId);
}
function getAllNFTs() public view returns(ListedToken[] memory) {
uint nftCount = _tokenIds.current();
ListedToken[] memory tokens = new ListedToken[](nftCount);
uint currentIndex = 0;
for(uint i=0; i<nftCount; i++) {
uint currentId = i+1;
ListedToken storage currentItem = idToListedToken[currentId];
tokens[currentIndex] = currentItem;
currentIndex += 1;
}
return tokens;
}
function getMyNFTs() public view returns (ListedToken[] memory) {
uint totalItemCount = _tokenIds.current();
uint itemCount = 0;
uint currentIndex = 0;
uint currentId;
for(uint i=0; i < totalItemCount; i++)
{
if(idToListedToken[i+1].owner == msg.sender || idToListedToken[i+1].seller == msg.sender){
itemCount += 1;
}
}
ListedToken[] memory items = new ListedToken[](itemCount);
for(uint i=0; i < totalItemCount; i++) {
if(idToListedToken[i+1].owner == msg.sender || idToListedToken[i+1].seller == msg.sender) {
currentId = i+1;
ListedToken storage currentItem = idToListedToken[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
function executeSale(uint256 tokenId) public payable {
uint price = idToListedToken[tokenId].price;
require(msg.value == price, "please submit the relevant NFT price in order to purchase");
address seller = idToListedToken[tokenId].seller;
idToListedToken[tokenId].currentlyListed = true;
idToListedToken[tokenId].seller = payable(msg.sender);
_itemsSold.increment();
_transfer(address(this), msg.sender, tokenId);
approve(address(this), tokenId);
payable(owner).transfer(listPrice);
payable(seller).transfer(msg.value);
}
}
I tried different networks, but I have no choice except goerli because I will use alchemy Api.
You still need to get more Goerli ETH from faucets or from your other peers.
Try that and see if it will work
Finally I switched from INFURA to ALCHEMY and following the instructions here:
https://hardhat.org/tutorial/deploying-to-a-live-network
it worked!
My contract for ERC1155 marketplace to mint buy and sell the NFT.
The nft is getting minted , However the NFT is not showing in market place and not able to purchase. I am facing this error.I have also applied setApprovedforAll method while minting still no help.
Should create and execute market sales:
Error: VM Exception while processing transaction: reverted with reason string 'ERC1155: caller is not owner nor approved'
at NFT1155.balanceOf (#openzeppelin/contracts/token/ERC1155/ERC1155.sol:71)
at NFT1155.isApprovedForAll (#openzeppelin/contracts/token/ERC1155/ERC1155.sol:110)
at NFT1155.createMarketSale (contracts/NFT1155.sol:165)
at async HardhatNode._mineBlockWithPendingTxs (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1772:23)
at async HardhatNode.mineBlock (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:466:16)
at async EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1496:18)
at async HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:118:18)
at async EthersProviderWrapper.send (node_modules/#nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)
My contract for ERC1155 marketplace to mint buy and sell the NFT.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
import "#openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "hardhat/console.sol";
contract NFT1155 is ERC1155, Ownable, ERC1155Supply {
//contract address goes here and id will be dynamic and will be passed in the _mint function calls
//example https://ipfs.io/ipfs/QmT51bbxTbSiYGcF2X39sG6DGYyAX2413A1sZfiACMgJGP?filename={id}.json
//if the if id 1 then https://ipfs.io/ipfs/QmT51bbxTbSiYGcF2X39sG6DGYyAX2413A1sZfiACMgJGP?filename=1.json will return the data that needs to be minted
constructor() ERC1155("") {}
mapping(uint256 => string) internal _tokenURIs;
mapping(uint256 => MarketItem) private idToMarketItem;
Counters.Counter private _itemsSold;
struct MarketItem {
uint256 tokenId;
address payable seller;
address payable owner;
uint256 price;
bool sold;
}
event MarketItemCreated(
uint256 indexed tokenId,
address seller,
address owner,
uint256 price,
bool sold
);
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
//To chnage the URL String after the contract is deployed
function setURI(string memory newuri) public onlyOwner {
_setURI(newuri);
}
function mintToken(
string memory tokenURI,
uint256 amount,
uint256 price
) public returns (uint256) {
uint256 newItemId = _tokenIds.current();
_mint(address(this), newItemId, amount, "");
_setTokenUri(newItemId, tokenURI);
//createMarketItem(newItemId, price, amount);
_tokenIds.increment();
return newItemId;
}
function createMarketItem(
uint256 tokenId,
uint256 price,
uint256 amount
) private {
require(price > 0, "Price must be at least 1 wei");
idToMarketItem[tokenId] = MarketItem(
tokenId,
payable(msg.sender),
payable(address(this)),
price,
false
);
setApprovalForAll(address(this), true);
safeTransferFrom(msg.sender, address(this), tokenId, amount, "");
emit MarketItemCreated(
tokenId,
msg.sender,
address(this),
price,
false
);
}
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _value,
bytes calldata _data
) external returns (bytes4) {
return
bytes4(
keccak256(
"onERC1155Received(address,address,uint256,uint256,bytes)"
)
);
}
function _setTokenUri(uint256 tokenId, string memory tokenURI) private {
_tokenURIs[tokenId] = tokenURI;
}
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public onlyOwner {
_mintBatch(to, ids, amounts, data);
}
// The following functions are overrides required by Solidity.
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal override(ERC1155, ERC1155Supply) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
/* allows someone to resell a token they have purchased */
function resellToken(
uint256 tokenId,
uint256 price,
uint256 amount
) public payable {
require(
idToMarketItem[tokenId].owner == msg.sender,
"Only item owner can perform this operation"
);
idToMarketItem[tokenId].sold = false;
idToMarketItem[tokenId].price = price;
idToMarketItem[tokenId].seller = payable(msg.sender);
idToMarketItem[tokenId].owner = payable(address(this));
_itemsSold.decrement();
safeTransferFrom(msg.sender, address(this), tokenId, amount, "");
}
/* Creates the sale of a marketplace item */
/* Transfers ownership of the item, as well as funds between parties */
function createMarketSale(uint256 tokenId, uint256 amount) public payable {
uint256 price = idToMarketItem[tokenId].price;
address seller = idToMarketItem[tokenId].seller;
console.log(
" ~ file: NFT1155.sol ~ line 147 ~ createMarketSale ~ price",
msg.value,
price
);
// require(
// msg.value == price,
// "Please submit the asking price in order to complete the purchase"
// );
idToMarketItem[tokenId].owner = payable(msg.sender);
idToMarketItem[tokenId].sold = true;
idToMarketItem[tokenId].seller = payable(address(0));
_itemsSold.increment();
safeTransferFrom(address(this), msg.sender, tokenId, amount, "");
setApprovalForAll(address(this), true);
// payable(owner).transfer(listingPrice);
payable(seller).transfer(msg.value);
}
/* Returns all unsold market items */
function fetchMarketItems() public view returns (MarketItem[] memory) {
uint256 itemCount = _tokenIds.current();
uint256 unsoldItemCount = _tokenIds.current() - _itemsSold.current();
uint256 currentIndex = 0;
MarketItem[] memory items = new MarketItem[](unsoldItemCount);
for (uint256 i = 0; i < itemCount; i++) {
if (idToMarketItem[i + 1].owner == address(this)) {
uint256 currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
/* Returns only items that a user has purchased */
function fetchMyNFTs() public view returns (MarketItem[] memory) {
uint256 totalItemCount = _tokenIds.current();
uint256 itemCount = 0;
uint256 currentIndex = 0;
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].owner == msg.sender) {
itemCount += 1;
}
}
MarketItem[] memory items = new MarketItem[](itemCount);
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].owner == msg.sender) {
uint256 currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
/* Returns only items a user has listed */
function fetchItemsListed() public view returns (MarketItem[] memory) {
uint256 totalItemCount = _tokenIds.current();
uint256 itemCount = 0;
uint256 currentIndex = 0;
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].seller == msg.sender) {
itemCount += 1;
}
}
MarketItem[] memory items = new MarketItem[](itemCount);
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].seller == msg.sender) {
uint256 currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
}
The problem is that because of the way you are minting, you don't own the token, the contract does.
Since you don't own the token, it doesn't appear in marketplaces and you can't call approve or transfer because you are not the owner of the token.
Here is the culprit:
_mint(address(this), newItemId, amount, "");
You are minting to address(this) which is the address of the contract itself.
You'll need a way to send the token from the contract to whomever you want using a custom function, or the probably better solution, you can just mint to the address calling your mintToken function by doing:
_mint(msg.sender, newItemId, amount, "");
Best of luck!!
When You call safeTransferFrom, require statement is not passing
function safeTransferFrom(address from,address to,uint256 id,uint256 amount,bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
Most likely you are transferring a token from the account that does not own the token,
You are using safeTransferFrom which is a public function. Try using _safeTransferFrom.You should add a custom function users can call, and internally use _safeTransferFrom
after reading many post i can't found the issues about this Smart contract who compile but it think i miss something about the inheritance and the Abstract contract.
This is the SC :
// solium-disable linebreak-style
pragma solidity >=0.4.21 <0.6.0;
import "../node_modules/#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "../node_modules/#openzeppelin/contracts/math/SafeMath.sol";
/**
* #title Ownable
* #dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address payable public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* #dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor (Ownable) public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* #dev Allows the current owner to transfer control of the contract to a newOwner.
* #param newOwner The address to transfer ownership to.
*/
function transferOwnership(address payable newOwner) public onlyOwner {
require(newOwner != address(0));
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
contract Sample is Ownable {
event NewResource (uint resourceId, string name , uint quality);
uint qualityUnits = 16;
uint qualityModulo = qualityUnits;
uint cooldownTime = 1 days;
struct Resource {
string name;
uint quality;
uint32 rarity;
uint256 cooldownTime;
uint16 stockGain;
uint16 stockLoss;
uint32 readyTime;
uint256 extractionTime;
uint256 extractionId;
uint256 magnetiteId;
uint256 hematiteId;
uint256 class;
uint256 sediments;
uint qualityUnits;
}
//mapping address and apply stocks
mapping (uint => address) public resourceToOwner;
mapping (address => uint) ownerResourceGain;
Resource[] public resources;
/// #dev function to crack the resource stacks
function _createResource (string memory _name , uint _quality) internal {
uint id = resources.push(Resource(_name,_quality ,1 , uint256( now + cooldownTime), 0 , 0, 0,
0, 0, 0, 0, 0, 0, 16) )+1;
resourceToOwner[id] = msg.sender;
ownerResourceGain[msg.sender]++;
emit NewResource(id, _name , _quality);
}
//function to generate rand stats for resources
function _generateRandomQuality(string memory _str ) private view returns (uint) {
uint rand = uint(keccak256(abi.encode(_str)));
return rand % qualityModulo;
}
//function to generate the resource stacks
function createResourceStack(string memory _name) public {
require(ownerResourceGain[msg.sender] ==0);
uint randomQuality = _generateRandomQuality(_name);
randomQuality = randomQuality - randomQuality % 100;
_createResource(_name, randomQuality);
}
}
contract CoreRefined is Sample {
//address public newContractAddress;
function getResourcesStats(uint256 _id)
external
view
returns (
bool isRefiningInProcess,
bool isReady,
uint256 cooldownTime,
//uint256 nextActionAt,
uint256 extractionTime,
uint256 extractionId,
uint256 magnetiteId,
uint256 hematiteId,
uint256 class,
uint256 sediments
)
{
Resource storage stats = resources[_id];
isRefiningInProcess = (stats.quality != 0);
isReady = (stats.cooldownTime <= block.number);
cooldownTime = uint256(stats.cooldownTime);
extractionTime = uint256(stats.extractionTime);
extractionId = uint256(stats.extractionId);
magnetiteId = uint256(stats.magnetiteId);
hematiteId = uint256(stats.hematiteId);
class = uint256(stats.class);
sediments = stats.sediments;
}
}
/// #title RefiningInterface for resource modification called refining
/// #dev Refining function inside for improving stats of resources.
contract RefiningInterface is Sample {
function refining(uint256 _id) external view returns (
bool isRefiningInProcess,
bool isReady,
uint256 cooldownTime,
uint256 nextActionsAt,
uint256 extractionTime,
uint256 extractionId,
uint256 magnetiteId,
uint256 hematiteId,
uint256 class,
uint256 sediments
);
}
contract ResourceRefined is Sample , CoreRefined {
ResourceRefined CoreRefinedContract;
modifier onlyOwnerOf(uint _resourceId) {
require(msg.sender == resourceToOwner[_resourceId]);
_;
}
function SetAnotherContractAddress (address _address) external onlyOwner {
CoreRefinedContract
= ResourceRefined(_address);
}
function triggerCooldown (Resource storage _resource ) internal {
_resource.readyTime = uint32(now+cooldownTime);
}
function _isReady ( Resource storage _resource ) internal view returns (bool) {
return (_resource.readyTime <= now);
}
function refinedAndMultiply( uint _resourceId, uint _targetQuality, string memory _types) internal onlyOwnerOf(_resourceId) {
Resource storage myResource = resources[_resourceId];
require(_isReady(myResource));
_targetQuality % qualityModulo;
uint newQuality = (myResource.quality + _targetQuality) / 2;
if(keccak256(abi.encode((_types))) == keccak256(abi.encode("Resources"))) {
newQuality = newQuality - newQuality % 100 + 99;
}
_createResource("NoName", newQuality);
triggerCooldown(myResource);
}
function refineOnInterface(uint256 _resourceId, uint256 _idResources ) public {
uint256 materialUsed;
(,,,,,,,,materialUsed) = CoreRefinedContract.getResourcesStats(_idResources);
refinedAndMultiply(_resourceId,materialUsed,"Resources");
}
}
contract ResourceHelper is ResourceRefined {
//cost ether for rarityUp fee
uint rarityForFee = 0.001 ether;
//modify rarity !=not LEVEL
modifier aboveCostLevel (uint _rarity ,uint _resourceId){
require(resources[_resourceId].rarity >= _rarity);
_;
}
//function to withdraw FIX ISSUE
/*function withdraw() external onlyOwner {
owner.transfer(this).balance;
}*/
//rarityfee for resources improvements
function setRarityFee(uint _fee) external onlyOwner {
rarityForFee = _fee;
}
//Rarity improvement function
/// #dev this function is set by using RefinedResource.sol contract in order to gain better resources
function rarityUp(uint _resourceId) external payable {
require(msg.value == rarityForFee);
resources[_resourceId].rarity++;
}
//change the name of resources
function changeName(uint _resourceId, string calldata _Newname) external aboveCostLevel(2, _resourceId) onlyOwnerOf (_resourceId){
resources[_resourceId].name = _Newname;
}
//change the qualityUnits
function changeQualityUnits(uint _resourceId, uint _newQualityUnits) external aboveCostLevel(2, _resourceId) onlyOwnerOf (_resourceId) {
resources[_resourceId].qualityUnits = _newQualityUnits;
}
//grabe the resources ! array of it.
function getTheResourceToOwner( address _owner) external view returns (uint[] memory) {
uint[] memory result = new uint[](ownerResourceGain[_owner]);
uint counter = 0;
//loop
for (uint i = 0; i < resources.length; i++) {
if (resourceToOwner[i] == _owner){
result[counter] = i;
counter++;
}
}
return result;
}
}
contract ResourceUp is ResourceHelper {
uint randNonce = 0;
uint resourceUpProba = 70;
/*function randMod(uint _modulus) internal returns(uint) {
randNonce++;
return uint(keccak256( (abi.encodePacked(now, msg.sender,randNonce))) % uint(_modulus));
}*/
function setUp(uint _resourceId, uint _targetId) external onlyOwnerOf(_resourceId) {
Resource storage myResource = resources[_resourceId];
Resource storage anotherResource = resources[_targetId];
uint rand = 100;
if (rand <= resourceUpProba) {
myResource.stockGain++;
myResource.rarity++;
anotherResource.stockLoss++;
refinedAndMultiply(_resourceId, anotherResource.quality, "resource");
} else {
myResource.stockLoss++;
anotherResource.stockGain++;
triggerCooldown(myResource);
}
}
}
contract Harvest is ResourceUp, ERC721 {
using SafeMath for uint256;
mapping (uint => address) resourceApproval;
function balanceOf(address _owner) public view returns (uint256 _balance) {
return ownerResourceGain[_owner];
}
function ownerOf(uint256 _tokenId) public view returns (address _owner) {
return resourceToOwner[_tokenId];
}
function _transfer(address _from, address _to, uint256 _tokenId) private {
ownerResourceGain[_to] = ownerResourceGain[_to].add(1);
ownerResourceGain[msg.sender] = ownerResourceGain[msg.sender].sub(1);
resourceToOwner[_tokenId] = _to;
_transfer(_from, _to, _tokenId);
}
function transferTo(address _to, uint256 _tokenId) public onlyOwnerOf(_tokenId) {
transferTo(_to, _tokenId);
}
function approve(address _to, uint256 _tokenId) public onlyOwnerOf(_tokenId) {
resourceApproval[_tokenId] = _to;
emit Approval(msg.sender, _to, _tokenId);
}
function harvest(uint256 _tokenId) public {
require(resourceApproval[_tokenId] == msg.sender);
address owner = ownerOf(_tokenId);
_transfer(owner, msg.sender, _tokenId);
}
}
My depoy js file :
const Harvest = artifacts.require("Harvest");
module.exports = function(deployer) {
deployer.deploy(Harvest)
};
The output of the truffle migrate
* Import abstractions into the '.sol' file that uses them instead of deploying them separately.
* Contracts that inherit an abstraction must implement all its method signatures exactly.
* A contract that only implements part of an inherited abstraction is also considered abstract.
verions :
Truffle v5.1.9 (core: 5.1.9)
Solidity v0.5.16 (solc-js)
Node v10.16.3
Web3.js v1.2.1
Thank you for your support.
The problem is with Ownable constructor
constructor (Ownable) public {
owner = msg.sender;
}
It is defined in a way that it will receive one parameter of type Ownable.
To fix the error define it without any input parameter:
constructor() public {
owner = msg.sender;
}