Testing a Flash Loan Smart Contract - Have some issues - blockchain

I am making a smart contract as I'm still learning solidity and practicing. I wrote the code, and I am receiving this error on Remix:
contracts/flash.sol:8:1: ParserError: Expected pragma, import directive or contract/interface/library/struct/enum definition.
address private wallet = 0x7e31a8ba5cF188fd39f9aaCF667E9dFE2311A882;
^-----^
This is all the code that I have right now:
pragma solidity ^0.6.0;
import "https://github.com/aave/aave-solidity/contracts/AAVE.sol";
import "https://github.com/Uniswap/uniswap-v2-core/contracts/interfaces/IUniswapV2Pair.sol";
import "https://github.com/sushiswap/sushiswap-v2-core/contracts/interfaces/ISushiV2Pair.sol";
// Set the wallet address
address private wallet = 0x0000000000000000000000000;
// Set the contract addresses
address private aave = 0x7deB5e830be29F91E298ba5FF1356BB7fC8B8C9D; // AAVE contract address
address private uniswap = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f; // Uniswap contract address
address private sushiswap = 0x6b3595068778dd592e39a122f4f5a5cf09c90fe2; // SushiSwap contract address
// Set the token addresses
address private eth = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // ETH token address
address private ape = 0x27Dce1e12396F3a2B49E4FdD7a4C9d938E5e5F97; // APE token address
// Set the contract ABIs
AAVE aaveContract;
IUniswapV2Pair uniswapContract;
ISushiV2Pair sushiswapContract;
constructor() public {
aaveContract = AAVE(aave);
uniswapContract = IUniswapV2Pair(uniswap);
sushiswapContract = ISushiV2Pair(sushiswap);
}
// Borrow 100 ETH from AAVE
function borrowFromAAVE() public {
aaveContract.borrow(eth, 100 ether, wallet);
}
// Swap 20 ETH to APE on SushiSwap
function swapETHtoAPEonSushiSwap(uint amount) public {
sushiswapContract.swap(amount ether, 10**18, ape, wallet, address(this));
}
// Swap 80 ETH to APE on Uniswap
function swapETHtoAPEonUniswap(uint amount) public {
uniswapContract.swapETHForExactTokens(amount ether, 10**18, ape, wallet, address(this));
}
// Swap all APE to ETH on SushiSwap
function swapAPEtoETHonSushiSwap(uint amount) public {
sushiswapContract.swap(amount, 10**18, eth, wallet, address(this));
}
// Pay back the loan to AAVE
function payBackLoanToAAVE() public {
// First, check if the wallet has sufficient balance to pay back the loan
require(wallet.balance >= aaveContract.borrowBalance(eth, wallet), "Insufficient balance to pay back the loan.");
// Pay back the loan
aaveContract.repayBorrow(eth, wallet);
}
// Keep the profit in the wallet
function keepProfitInWallet(uint amount) public {
// First, check if the contract has sufficient balance to transfer the profit to the wallet
require(address(this).balance >= amount, "Insufficient balance in the contract.");
// Transfer the profit to the wallet
wallet.transfer(amount);
}
what am I doing wrong?
The error is showing where Wallet, AAVE, Uniswap and Sushiswap are located.
I tried many things, it keeps showing me the same error, please let me know what the issue is to learn more as I am a beginner, much appreciated champs

You need to specify a contract (similar to class in other OOP languages) in which you want the wallet property declared.
pragma solidity ^0.6.0;
import "https://github.com/aave/aave-solidity/contracts/AAVE.sol";
import "https://github.com/Uniswap/uniswap-v2-core/contracts/interfaces/IUniswapV2Pair.sol";
import "https://github.com/sushiswap/sushiswap-v2-core/contracts/interfaces/ISushiV2Pair.sol";
contract MyContract {
// Set the wallet address
address private wallet = 0x0000000000000000000000000;
// rest of your code
}

Related

Solidity Transaction Issue

i'm facing some weird issues, or well, things i'm not understanding. I'm still pretty new with solidity tho, anyway, i'm trying to create a staking contract, based on an ERC20 token i created. I call the stake function with ethers.js and pass the amount with it. The staking contract saves some info and forwards receiver address and amount to the ERC20 transfer function.
async function stake () {
await stakeContract.stake(1);
}
function stake (uint256 _amount) public {
require(_amount > 0, "You must stake more than 0");
require(_amount < ercToken.balanceOf(msg.sender), "The amount exceeds your balance");
addressToStaked[msg.sender].push(Stakes(block.timestamp, _amount));
totalStakes[msg.sender] += 1;
ercToken.transfer(address(ercToken), _amount);
}
The transfer function then forwards the data to the internal _transfer function shown below. The problem is that, even if i do have enough tokens in my wallet, the _transfer function still fails with error: Amount exceeds balance.
I've double checked the mapping saving the balance and it works.
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
It seems you made a mistake on this line of the staking contract.
function stake (uint256 _amount) public {
...
ercToken.transfer(address(ercToken), _amount);
}
The above line means, transfer "_amount" token to "ercToken" address from staking contract. So there should be some amounts ( >_amount ) of tokens on staking contract. But as you mentioned, you only have enough tokens on your wallet, not on staking contract.
Plz use "transferFrom" function or "safeTransferFrom" function of "SafeERC20" library to solve the issue.

deploy erc721 contracts from a simple or factory contract

I want to deploy erc721 contracts from a simple factory contract and i have this error when I try to upload NFT - "transfer to non ERC721Receiver implementer", "data"enter image description here
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./ezeynftFactory.sol";
contract ezeNFT {
uint256 public tokenCounter;
constructor(){
tokenCounter = 201;
}
function _mintNewNFT( string memory name, string memory symbol, string memory tokenUri)public{
uint256 newTokenId = tokenCounter;
ezeynftFactory nfts = new ezeynftFactory(name,symbol,tokenUri,newTokenId);
tokenCounter += 1;
}
}
// SPDX-License-Identifier: MIT
pragma experimental ABIEncoderV2;
pragma solidity >=0.6.0 <0.8.0;
import "../ERC721/ERC721.sol";
contract ezeynftFactory is ERC721 {
constructor(string memory name, string memory symbol,string memory tokenURI,uint tokenID)
ERC721(name,symbol)
{
_safeMint(msg.sender, tokenID);
_setTokenURI(tokenID,tokenURI);
}
}
The OpenZeppelin _safeMint() function tries to invoke onERC721Received() on the receiver if the receiver is a contract (which your ezeNFT is). And reverts the transaction if it doesn't receive the expected response (which doesn't receive, so it reverts).
There are two solutions to your problem.
Either implement the onERC721Received() function on your ezeNFT contract (the token receiver), returning the expected response. See ERC721TokenReceiver interface in the ERC-721 standard definition for more info.
contract ezeNFT {
uint256 public tokenCounter;
constructor(){
tokenCounter = 201;
}
function _mintNewNFT( string memory name, string memory symbol, string memory tokenUri) public {
uint256 newTokenId = tokenCounter;
ezeynftFactory nfts = new ezeynftFactory(name,symbol,tokenUri,newTokenId);
tokenCounter += 1;
}
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4) {
// TODO validate if you want to accept tokens only from certain collections
// return the expected response
return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
}
}
Or use the _mint() function, instead of _safeMint(), which doesn't perform the onERC721Received() call on the token receiver. So you won't have to implement it on ezeNFT.
contract ezeynftFactory is ERC721 {
constructor(string memory name, string memory symbol,string memory tokenURI,uint tokenID)
ERC721(name,symbol)
{
_mint(msg.sender, tokenID); // `_mint()` instead of `_safeMint()`
_setTokenURI(tokenID,tokenURI);
}
}

I try to deploy a contract on rinkeby testnet with some eth but there is an error occurred

The error I face in remix is Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted even if I have enough money to create a contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
// Get the latest ETH/USD price from chainlink price feed
import "#chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
contract FundMe {
// safe math library check uint256 for integer overflows
//mapping to store which address depositeded how much ETH
mapping(address => uint256) public addressToAmountFunded;
// array of addresses who deposited
address[] public funders;
//address of the owner (who deployed the contract)
address public owner;
constructor() public {
owner = msg.sender;
}
function fund() public payable {
// 18 digit number to be compared with donated amount
uint256 minimumUSD = 50 * 10 ** 18;
//is the donated amount less than 50USD?
require(getConversionRate(msg.value) >= minimumUSD, "You need to spend more ETH!");
//if not, add to mapping and funders array
addressToAmountFunded[msg.sender] += msg.value;
funders.push(msg.sender);
}
function getVersion() public view returns (uint256){
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
return priceFeed.version();
}
function getPrice() public view returns(uint256){
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
(,int256 answer,,,) = priceFeed.latestRoundData();
// ETH/USD rate in 18 digit
return uint256(answer * 10000000000);
}
function getConversionRate(uint256 ethAmount) public view returns (uint256){
uint256 ethPrice = getPrice();
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
// the actual ETH/USD conversation rate, after adjusting the extra 0s.
return ethAmountInUsd;
}
}
1)try downgrading your compiler version to 0.5
if that does not work try this
2)In remix try to increase your gas limit to probably 8000000
You need a receve/fallback function to send ETH to a contract. Try to add these to your contract code:
receive() external payable {
// React to receiving ether
}

Optimal way of handling NFT minting queue

I am doing a generative NFT project where the user purchases an NFT pack from (1 to 10) and there will be a service that generates up to 10 NFTs, uploads it to IPFS then returns it to the frontend. Frontend then prompts the user to approve the transaction which then mints the NFT to the user.
This flows takes some time especially at the generating part,
so I was thinking of creating a different flow that has a smart contract that holds a queue array. Instead of generating the NFT first, the user will join the queue in the smart contract, then a service that polls the queue array will start generating and minting anything in the queue.
However, if I do this flow, the service will have to be the one that pays the gas fee when minting,
so I was wondering if anyone could advise me on how to create a queue system in blockchain for this case?
contract YourContract is Ownable {
uint256 public maxAmount = 10;
uint256 public price = 10 ether;
function mint(address _to, uint256 _mintAmount) public payable {
// you can add more logic
require(_mintAmount > 0);
// Maybe currently user has no enough fund to mint all
// so it mints some now, will do later, depends on your contract logic
require(_mintAmount <= maxAmount);
// owner() is if your contract is inheriting from Ownable
// if you set the owner on your own inside constructor, use `owner`
// you are forcing the callee of the function to pay this amount
if (msg.sender != owner()) {
require(msg.value >= price * _mintAmount);
}
// after callee has paid, run the minting
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(_to, i);
}
}
}
this is the _safeMint in ERC721
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}

Gas required exceeds limit: 3000000.

pragma solidity ^0.4.16;
contract createNewToken {
uint256 total_ether_to_send;
address private owner;
//constructor
function createNewToken() public{
owner = msg.sender;
}
// client request for tokens by sending ether.
function requestForToken() public payable{
address sender = msg.sender;
uint value = msg.value;
total_ether_to_send = value;
require(sender.balance >= total_ether_to_send);
owner.transfer(total_ether_to_send);
total_ether_to_send = value / 2;
require(owner.balance >= total_ether_to_send);
sender.transfer(total_ether_to_send);
}
}
I have written this code in solidity in Remix IDE. The contract was successfully created but when I used it, it gave me an error saying "Gas required exceeds limit: 3000000. An important gas estimation might also be the sign of a problem in the contract code. Please check loops and be sure you did not sent value to a non payable function". I don't have much code written but its still gave me this error. Can anyone help?
First, your msg.value is already sent to your method, hence you don't need to check senders balance: require(sender.balance >= total_ether_to_send);.
Second, you don't have a fallback function in your contract to receive ether.
Third, you are trying to send 100% msg.value to owner and then send 50% of msg.value back to sender. Obviously you cannot spend 150% of msg.value without any additional funds on your contract. Here is example of working code:
function requestForToken() public payable{
address sender = msg.sender;
uint value = msg.value;
total_ether_to_send = value / 2;
require(this.balance >= total_ether_to_send);
owner.transfer(total_ether_to_send);
require(this.balance >= total_ether_to_send);
sender.transfer(total_ether_to_send);
}
function() payable {}