Solidity, Wrapping Eth from a contract - solidity

I'm trying to wrap Eth from an smart contract as I want to swap weth later in uniswap but I don't know how to import the WETH code from goerli scan WETH = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6;.
Following internet examples I accomplished wrapping Eth but all influencers just import a ERC20 library to create a new one. I don't understand why they are using this as they are not interacting with the right weth contract.
Here is the code I used but is just creating a new token. Can anyone give me some advice?
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
pragma abicoder v2;
import '#uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';
import '#uniswap/v3-periphery/contracts/libraries/TransferHelper.sol';
import '#openzeppelin/contracts/token/ERC20/ERC20.sol';
contract SwapExamples is ERC20 {
// For the scope of these swap examples,
// we will detail the design considerations when using `exactInput`, `exactInputSingle`, `exactOutput`, and `exactOutputSingle`.
// It should be noted that for the sake of these examples we pass in the swap router as a constructor argument instead of inheriting it.
// More advanced example contracts will detail how to inherit the swap router safely.
// This example swaps DAI/WETH9 for single path swaps and DAI/USDC/WETH9 for multi path swaps.
ISwapRouter public immutable swapRouter;
address payable [] private s_Wallets;
uint256 public walletA = address(this).balance;
// Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564
address public constant WETH = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6; //0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// For this example, we will set the pool fee to 0.3%.
uint24 public constant poolFee = 3000;
uint256 public UsdOut;
constructor(ISwapRouter _swapRouter) ERC20("Wrapped Ether", "WETH") {//ERC20("Wrapped Ether", "WETH")
swapRouter = _swapRouter;
}
function Deposit() public payable {
s_Wallets.push(payable(msg.sender));
}
function Mint() external payable {
_mint(address(this), address(this).balance);
}
}

You need not create a new ERC20 token.
Calling:
WETH.deposit.value(msg.value)();
helps you wrap your ETH and you don't need to import WETH code from anywhere.
After wrapping, you can then move on to swapping WETH for any other token on Uniswap like you said.

Related

How can I get metadata and my image to show up on OpenSea Testnet?

I followed along with Remix's beginner NFT course and successfully deployed a few NFTs using the Goerli testnet and their provided IPFS data. I uploaded my own image and metadata and can see it on IPFS but neither the metadata nor the image is populating on OpenSea.
Here is the code for the contract I am deploying:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts#4.4.0/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts#4.4.0/access/Ownable.sol";
contract Donation is ERC721, Ownable {
constructor() ERC721("Donation", "DONO") {}
function _baseURI() internal pure override returns (string memory) {
return "https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2";
}
function safeMint(address to, uint256 tokenId) public onlyOwner {
_safeMint(to, tokenId);
}
}
Please see the URL that I return for my metadata and subsequent link to my image. Is there anything you see that is immediately wrong that would indicate why nothing is populating (in the JSON file, code, or otherwise)?
For ERC721, the _baseURI will essentially be the base to be combined with the NFT's token id, so for example NFT with token ID 0 will have the tokenURI of:
https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2/0
which in this case after checking is invalid as https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2 should be the valid tokenURI itself. OpenZeppelin designed the ERC721 contract this way as it is the most gas-efficient way to create a standard ERC721 NFT. However, the drawback is that it made it difficult to provide modified URI for each token ID.
If you like to set tokenURI with different base for different token ID, then you should instead check ERC721URIStorage in the contract wizard. This way, the ERC721 NFT contract will have the _setTokenURI(tokenId, uri) function, which allows you to modify the tokenURI for different token ID. However, keep in mind that this will be very expensive on the user side as string inputs cost a lot in EVMs.
Hope this helps~

Solidity, swap on uniswapV3

I want to implement a swap on UniV3 but the follow error appears:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted
I have approved the Weth via etherscan goerli so I don't know why is sending me this error.Any advice??
Here is the code:
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
pragma abicoder v2;
import '#uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';
import '#uniswap/v3-periphery/contracts/libraries/TransferHelper.sol';
contract SwapExamples {
// For the scope of these swap examples,
// we will detail the design considerations when using `exactInput`, `exactInputSingle`, `exactOutput`, and `exactOutputSingle`.
// It should be noted that for the sake of these examples we pass in the swap router as a constructor argument instead of inheriting it.
// More advanced example contracts will detail how to inherit the swap router safely.
// This example swaps DAI/WETH9 for single path swaps and DAI/USDC/WETH9 for multi path swaps.
ISwapRouter public immutable swapRouter;
// Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564
address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address public constant WETH = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6; //0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address public constant USDC = 0xEEa85fdf0b05D1E0107A61b4b4DB1f345854B952;//0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
// For this example, we will set the pool fee to 0.3%.
uint24 public constant poolFee = 3000;
uint256 public UsdOut;
constructor(ISwapRouter _swapRouter) {
swapRouter = _swapRouter;
}
/// #notice swapExactInputSingle swaps a fixed amount of DAI for a maximum possible amount of WETH9
/// using the DAI/WETH9 0.3% pool by calling `exactInputSingle` in the swap router.
/// #dev The calling address must approve this contract to spend at least `amountIn` worth of its DAI for this function to succeed.
/// #param amountIn The exact amount of DAI that will be swapped for WETH9.
/// #return amountOut The amount of WETH9 received.
function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) {
// msg.sender must approve this contract
// TransferHelper.safeApprove(WETH, address(this), amountIn);
// Transfer the specified amount of DAI to this contract.
TransferHelper.safeTransferFrom(WETH, msg.sender, address(this), amountIn); //Envia de la wallet a aquest contract, no necessito.
// Approve the router to spend DAI.
TransferHelper.safeApprove(WETH, address(swapRouter), amountIn);
// Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum.
// We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount.
ISwapRouter.ExactInputSingleParams memory params =
ISwapRouter.ExactInputSingleParams({
tokenIn: WETH,
tokenOut: USDC,
fee: poolFee,
recipient: msg.sender,
deadline: block.timestamp,
amountIn: amountIn,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
// The call to `exactInputSingle` executes the swap.
amountOut = swapRouter.exactInputSingle(params);
UsdOut = amountOut;
}
}

Foundry call smart contract from with EOA address

I am wtiting test case using Foundry. I want to call a custom smart contract function that changes the state of the smart contract called from a EOA so the msg.sender would be the EOA address. Here is my testing code:
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import {console} from "forge-std/console.sol";
import {stdStorage, StdStorage, Test} from "forge-std/Test.sol";
import {Utils} from "./utils/Utils.sol";
import {MyERC20} from "../MyERC20.sol";
contract BaseSetup is MyERC20, DSTest {
Utils internal utils;
address payable[] internal users;
address internal alice;
address internal bob;
function setUp() public virtual {
utils = new Utils();
users = utils.createUsers(5);
alice = users[0];
vm.label(alice, "Alice");
bob = users[1];
vm.label(bob, "Bob");
}
function test() {
this.customFunction(); // want to call this function as Alice as the caller
}
}
So, in the code above, customFunction is defined on the MyERC20 contract, and it changes the smart contract state. I want to call the function with different EOA accounts like alice and bob. Is it possible, and if so, what it the syntax for that?
I would recommend using the prank cheatcode in foundry for this.
It's pretty straight forward.
interface CheatCodes {
function prank(address) external;
}
contract Test is DSTest {
CheatCodes cheatCodes;
function setUp() public {
cheatCodes = CheatCodes(HEVM_ADDRESS);
}
function test() public {
// address(1337) is now the caller of customFunction
cheatCodes.prank(address(1337));
address(contract).customFunction();
}
}
This pranked caller will only persist for a single call. Then you will have to instantiate the caller again with the prank cheatCode on future calls to the contract. Alternatively there is also a cheatCode called startPrank which will allow the custom caller to persist until stopPrank is called. Hope this helps!

Burning Deployed ERC Tokens In an NFT Mint Function - Compiles, but Transaction Fails

I am very new to Solidity, and have recently been working on trying to learn the ropes. For reference, I have been using code from this video (https://www.youtube.com/watch?v=tBMk1iZa85Y) as a primer after having gone through the basic crypto zombies tutorial series.
I have been attempting to adapt the Solidity contract code presented in this video (which I had functioning just fine!) to require a Burn of a specified amount of an ERC-20 token before minting an NFT as an exercise for myself. I thought I had what should be a valid implementation which compiled in Remix, and then deployed to Rinkeby. I call the allowAccess function in Remix after deploying to Rinkeby, and that succeeds. But, when I call the mint function with the two parameters, I get: "gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? execution reverted."
If I still send the transaction, metamask yields "Transaction xx failed! Transaction encountered an error.".
I'm positive it has to do with "require(paymentToken.transfer(burnwallet, amounttopay),"transfer Failed");", though I'm not sure what's wrong. Below is my entire contract code. I'm currently just interacting with the Chainlink contract on Rinkeby as my example, since they have a convenient token faucet.
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol";
contract myNFTwithBurn is ERC721, Ownable {
address externalTokenAddress = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709; //Token Type to burn on minting
uint256 amounttopay = 5; //number of these tokens to burn
IERC20 paymentToken = IERC20(externalTokenAddress); //my code: create an interface of the external token
address burnwallet = 0x000000000000000000000000000000000000dEaD; //burn wallet
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
using Strings for uint256;
// Optional mapping for token URIs
mapping (uint256 => string) private _tokenURIs;
// Base URI
string private _baseURIextended;
constructor() ERC721("NFTsWithBurn","NWB") {
}
function setBaseURI(string memory baseURI_) external onlyOwner() {
_baseURIextended = baseURI_;
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
function allowAccess() public
{
paymentToken.approve(address(this), 5000000); //This is my attempt to allow the contract access to the user's external tokens, in this case Chainlink (paymentToken)
}
function mintItem(address to, string memory tokenURI)
public
onlyOwner
returns (uint256)
{
require(paymentToken.transfer(burnwallet, amounttopay),"transfer Failed"); //Try to transfer 5 chainlink to the burn wallet
_tokenIds.increment();
uint256 id = _tokenIds.current();
_mint(to, id);
_setTokenURI(id, tokenURI);
return id;
}
}
If anybody can at least point me to what I'm doing completely wrong in the code that I've added, please do! TIA!
I'm not sure why are you trying to burn link in order to mint and nft but first check if the link code does not have a require that check if the destination address is the burn address if it has then burn the link is not possible and you should use any other erc20 maybe your own erc20, also your contract probably does not have any link and if you want to transfer the link from the user you should do this in the contract paymentToken.transferFrom(msg.sender,destinationAddress,amount) and if the user previously approve your contract you will able to send the tokens, and i suppose that the purpose of the allowAccess function is to make the user approve the contract to move the tokens that will never work, the approve function let's anyone that call it approve any address to move an amount of tokens, the thing is that to know who is approving to let other to move the tokens the function use msg.sender to explain how this work take a look at this example
let's say that your contract is the contract A and the link contract is the contract B
now a user call allowAccess in the contract A, so here the msg.sender is the user because they call the function
now internally this function call approve on contract B, here the contract A is the msg.sender, because the contract is who call the function
so what allowAccess is really doing is making the contract approving itself to move their own tokens that I assume it doesn't have

safeTransfer with token erc1155 in solidity 0.8

I get this error
ERC1155: transfer to non ERC1155Receiver implementer when try to transfer to a smart contract I found this doc https://docs.openzeppelin.com/contracts/4.x/api/token/erc1155 but still don't know how to fix this do I have to abstract IERC1155Receiver interface in my holder token 1155
The receiving contract needs to implement the onERC1155BatchReceived() function based on the ERC-721 definition.
pragma solidity ^0.8;
contract MyContract {
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes memory _data) external returns(bytes4) {
// here you can (but don't have to) define your own logic - emit an event, set a storage value, ...
// this is the required return value described in the EIP-721
return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
}
}