I have this function called "exchangeCall" in my contract with which I can send an amount of its native ETH token ("values"), data in bytes ("callData") and an estimated gas ("estimatedGas") towards another contract ("target"). The purpose is to send the byte data ("callData"), which already contains a previously defined series of steps.
This script works perfectly when I try (for example) to exchange through the Uniswap contract, ETH (native token) for UNI (or another token).
However, when I try to do it the other way around by exchanging any token other than ETH for another one it generates an error.
In the following video you can find a more specific explanation through an example:
Videolink -> https://drive.google.com/file/d/1ujP5Q_-_PHpkDNb1Jeldo1HveReWZUMT/view
For my case, it is important that this code is made only in solidity (not web3 or similar).
I have already checked the permissions so that the non-native token can be used by the contract, it can be done with the other auxiliary functions present in the contract or through the IERC20 which is also invoked there.
I hope someone can help me, and I share the script code.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
pragma experimental ABIEncoderV2;
import {IERC20} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
contract SimpleExchange {
address payable owner;
// SOME TOKENS FOR TEST
address private immutable uniAddress =
0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984; // UNI TOKEN
address private immutable usdcAddress =
0xA2025B15a1757311bfD68cb14eaeFCc237AF5b43; // USDC TOKEN
address dexContractAddress =
0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45; // Contrato Objetivo
// FUNCTION FOR EXCHANGE
function exchangeCall(address target, bytes memory callData, uint values, uint estimatedGas) public payable returns (uint256 blockNumber) {
blockNumber = block.number;
(bool success, bytes memory ret) = target.call{value:values,gas:estimatedGas}(callData);
require(success);
}
//OPTIONAL FUNCTIONS FOR DEVELOPMENT TESTS
function approveUSDC(uint256 _amount) external returns (bool) {
return IERC20(usdcAddress).approve(dexContractAddress, _amount);
}
function allowanceUSDC() external view returns (uint256) {
return IERC20(usdcAddress).allowance(address(this), dexContractAddress);
}
function approveUNI(uint256 _amount) external returns (bool) {
return IERC20(uniAddress).approve(dexContractAddress, _amount);
}
function allowanceUNI() external view returns (uint256) {
return IERC20(uniAddress).allowance(address(this), dexContractAddress);
}
function getBalance(address _tokenAddress) external view returns (uint256) {
return IERC20(_tokenAddress).balanceOf(address(this));
}
function transfer(address _tokenAddress, address receiverAddr, uint receiverAmnt) public payable{
IERC20 token = IERC20(_tokenAddress);
token.transfer(receiverAddr, receiverAmnt);
}
function transferFrom(address sender, address recipient, uint256 amount,address token) external returns (bool){
IERC20(token).transferFrom(sender,recipient,amount);
return true;
}
function withdraw(address _tokenAddress) external {
IERC20 token = IERC20(_tokenAddress);
token.transfer(msg.sender, token.balanceOf(address(this)));
}
// Function to receive Ether. msg.data must be empty
receive() external payable {}
// Fallback function is called when msg.data is not empty
fallback() external payable {}
}
Related
I'm getting an error when trying to compile my own custom Flashswap smart contract. After compiling using Hardhat on VS Code, it throws up an error for the Pancakefactory script.
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IPancakeFactory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
require(msg.sender == feeToSetter, 'Pancakeswap: FORBIDDEN');
feeTo = _feeTo;
}
function setFeeToSetter(address) external;
require(msg.sender == feeToSetter, 'Pancakeswap: FORBIDDEN');
feeToSetter = _feeToSetter;
}
}
The error is for the line beneath function setFeeTo(address) external;. The parser error that's thrown up is "Expected identifier but got ( ".
Am I writing the line require(msg.sender == feeToSetter, 'Pancakeswap: FORBIDDEN'); inncorrectly? Is there something missing here or do I need to change where the brackets are?
I'm new at solidity.
I've put here the snippet of code:
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract Example {
AggregatorV3Interface internal priceFeed;
/**
* Network: Goerli
* Aggregator: ETH/USD
* Address: 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e
*/
constructor() {
priceFeed = AggregatorV3Interface(
0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e
);
owner = msg.sender;
}
}
And if you see, the parameter that I need to send to AggregatorV3Interface is static 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e.
To me, that doesn't look optimized enough. Because right now, I'm playing with this function for Goerli, but if I were to deploy this contract to Etherium mainnet, I would have to change that address manually. Even if you go to chainlink website, they have it like this. https://docs.chain.link/data-feeds/price-feeds/#solidity
Is there a better way? I would like to have some variable that I would set, and read from it? Or maybe some custom variable setting from hardhat, that I'm using.
priceFeed = AggregatorV3Interface(env.proccess.address); Would be desired, or anything dynamic.
Usual approach is to pass the address to Solidity constructor from a JS (or any other offchain language) script that reads from the environment variable.
.env
AGGREGATOR_ADDRESS=0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e
JS deployer script
require("dotenv").config();
const hre = require("hardhat");
async function main() {
const factory = await hre.ethers.getContractFactory("Example");
// pass constructor arguments to the `deploy()` function
const contract = await factory.deploy(process.env.AGGREGATOR_ADDRESS);
await contract.deployed();
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Solidity contract
pragma solidity ^0.8;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract Example {
AggregatorV3Interface internal priceFeed;
constructor(address _aggregator) {
priceFeed = AggregatorV3Interface(_aggregator);
}
}
I'm being honest this code is taken from a website that is supposed to ease the creation of a smart contract/token on the binance smart chain. (short backstory: Me and some friends thought it would be fun to have our own token to e.g. take bets, play poker whatsoever and are now trying to create our own through deploying our smart contract on the BSC)
Here is a link to the template I used: https://github.com/binance-chain/bsc-genesis-contract/blob/master/contracts/bep20_template/BEP20Token.template
I am trying to compile the code but in line 352 the error "expected primary expression" occurs. What does that mean? I am really just a layman. The token is supposed to be called Omega and the Symbol OHM.
Thank you for your suggestions!
The linked contract contains this function which causes the syntax error.
constructor() public {
_name = {{TOKEN_NAME}};
_symbol = {{TOKEN_SYMBOL}};
_decimals = {{DECIMALS}};
_totalSupply = {{TOTAL_SUPPLY}};
_balances[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
I'm assuming that it was the contract author's intention to use these placeholders as a way to point out where you can fill in your own values.
After you replace the placeholders with real values, the contract compiles successfully.
constructor() public {
_name = "MyToken";
_symbol = "MyT";
_decimals = 18;
_totalSupply = 1000000000000000000;
_balances[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
I am trying to create a struct and add mapping in such a way that it can be retrieved later on using its address using the below code.
pragma solidity ^0.8.0;
contract Courses {
struct Instructor {
uint age;
string fName;
string lName;
}
mapping (address => Instructor) instructors;
address[] public instructorAccts;
function setInstructor(address _address, uint _age, string _fName, string _lName) public {
var instructor = instructors[_address]; //ERROR HERE
instructor.age = _age;
instructor.fName = _fName;
instructor.lName = _lName;
instructorAccts.push(_address) -1;
}
}
However, I am getting an error at the line var instructor = instructors[_address]
The error is ParserError: Expected primary expression
I am unable to understand what the issue is and how to resolve it. Could anyone help with this?
Solidity uses typed variables, doesn't have the generic var keyword (that is used in JavaScript for example).
When declaring reference types (in your case string and struct), you need to specify their data location - in your case memory for the string argument. And either memory or storage for the struct depending on whether you want to set the values just in the context of the setInstructor() function (location memory), or if you want to set its values in the contract storage (location storage).
function setInstructor(address _address, uint _age, string memory _fName, string memory _lName) public {
// either `memory` or `storage` depending on your use case
Instructor storage instructor = instructors[_address];
// ... rest of your code
There also is a syntax error on this line
instructorAccts.push(_address) -1;
you can fix it by removing the -1
instructorAccts.push(_address);
I am running a simple code from SimpleStorage example and just added few lines on top of it which I was using for my other contracts. The contract compiles fine from truffle. But on the Cakeshop Integrated IDE it shows compilation error.
pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;
contract SimpleStorage {
uint public storedData;
event Change(string message, uint newVal);
function SimpleStorage(uint initVal) {
Change("initialized", initVal);
storedData = initVal;
}
function set(uint x) {
Change("set", x);
storedData = x;
}
function get() constant returns (uint retVal) {
return storedData;
}
}
It should compile on the cakeshop web UI as it compiles on local machine
Utilizing Remix, it seems the following could be potential issues with your contract:
You are using the Contract name for the constructor. You should use the constructor keyword instead.
All of your functions are missing visibility modifiers. Consider adding the public modifier to each function including the constructor.
Events should be invoked using the emit keyword. Example: emit Change("set", x);