I'm trying to add liquidity to my smart contract on Uniswap, however whenever I try to add liquidity, I can approve the transaction, but hitting apply does nothing. The Javascript console shows an error saying: not able to predict gas gee. There's also a problem with TransferFrom.
function transfer(address to, uint value) public returns(bool) {
require(balanceOf(msg.sender) >= value, 'balance too low');
//burn&tax
burn(msg.sender,burnTaxFee(value));
sendDev(msg.sender,devTaxFee(value));
balances[to] += value; //send the value - burnt tokens to reciever
balances[msg.sender] -= value ; //subtract value sent from sender.
emit Transfer(msg.sender, to, value);
return true;
}
function transferFrom(address from, address to, uint value) public returns(bool) {
require(balanceOf(from) >= value, 'balance too low');
require(allowance[from][msg.sender] >= value, 'allowance too low');
//burn&tax
burn(msg.sender,burnTaxFee(value));
sendDev(msg.sender,devTaxFee(value));
balances[to] += value; //send the value - burnt tokens to reciever
balances[from] -= value; //subtract value sent from sender.
emit Transfer(from, to, value);
return true;
}
I'm thinking it might have to do with my smart contract? for each transfer, I also do 2 separate transfers that go into two separate wallets. Do multiple transfers triggered by the normal transfer function cause problems with uniswap?
Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"code":-32603,"message":"execution reverted: TransferHelper: TRANSFER_FROM_FAILED","data":{"originalError":{"code":3,"data":"0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000245472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c454400000000000000000000000000000000000000000000000000000000","message":"execution reverted: TransferHelper: TRANSFER_FROM_FAILED"}}}, method="estimateGas", transaction={"from":"0xA6486944b1119CDAB743694873e28ad8eF3f89e2","to":"0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D","value":{"type":"BigNumber","hex":"0x1717b72f0a4000"},"data":"0xf305d71900000000000000000000000054620e1c1c39d689fc73214bb1de16f743214dce0000000000000000000000000000000000000000000113d788ba2b887b6c80000000000000000000000000000000000000000000000113d788ba2b887b6c8000000000000000000000000000000000000000000000000000001717b72f0a4000000000000000000000000000a6486944b1119cdab743694873e28ad8ef3f89e20000000000000000000000000000000000000000000000000000000060c1817e","accessList":null}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.2.0)
Another idea I had was that I'm not using the SafeMath library, would non-safemath equations cause issues with Uniswap?
Related
I want the following function to activate after 6 mins(360 secs) of contract deployment because my task requires a withdrawal lock. should I put if (block.timestamp > 360) before the function or inside the function just before the remaining code?
function withdraw(uint256 amount) external updateReward(msg.sender) nonReentrant {
if (block.timestamp > 360) {
s_totalSupply -= amount;
s_balances[msg.sender] -= amount;
emit WithdrewStake(msg.sender, amount);
// transfer: send tokens from contract back to msg.sender.
bool success = s_stakingToken.transfer(msg.sender, amount);
if (!success) {
revert TransferFailed(); // revert resets everything done in a failed transaction.
}}
}
But I'm not even sure if if (block.timestamp > 360) is the right code for this case.
Figured it out for you my brother:
pragma solidity ^0.8.7;
import "hardhat/console.sol";
contract TimeTest{
uint256 public initialTime;
constructor () public{
initialTime = block.timestamp;
}
function withdraw() public {
uint256 nowTime = block.timestamp-initialTime; // time between deployment of contract and now.
console.log(nowTime);
if (nowTime > 60) {
console.log("Time is up");
}
}
}
The reason why you have to do that is because block.timestamp doesnt represent the time since the contract was deployed, but the time since the unix epoch. The name of the variable is a little misleading.
You can find more info here: https://docs.soliditylang.org/en/v0.8.13/units-and-global-variables.html
Or here:https://programtheblockchain.com/posts/2018/01/12/writing-a-contract-that-handles-time/ (just know that "now" doesnt exist anymore since version 0.0.7. "now" was equivalent to "block.timestamp". But the tutorial is still valid if you replace "now" with "block.timestamp".
I'm wondering what's the difference from
contract TestToken {
mapping(address => uint) balance;
error InsufficientBalance(uint256 available, uint256 required);
function transfer(address to, uint256 amount) public {
if (amount > balance[msg.sender])
// Error call using named parameters. Equivalent to
// revert InsufficientBalance(balance[msg.sender], amount);
revert InsufficientBalance({
available: balance[msg.sender],
required: amount
});
balance[msg.sender] -= amount;
balance[to] += amount;
}
// ...
}
and
contract TestToken {
mapping(address => uint) balance;
error InsufficientBalance(uint256 available, uint256 required);
function transfer(address to, uint256 amount) public {
require(balance[msg.sender]<amount, "Insufficient Balance");
balance[msg.sender] -= amount;
balance[to] += amount;
}
// ...
}
to handle error in solidity
From the low-level standpoint, both approaches are the same. Both throw an exception with an array of bytes as the exception data.
You can catch both errors in the low-level catch (bytes memory) block
function foo() public {
try this.transfer(address(0x123), 2) {
// ok
} catch (bytes memory data) {
// returns either the encoded object or the encoded string
}
}
But you can only catch the string-encoded error with the "regular" catch Error(string memory) block
function foo() public {
try this.transfer(address(0x123), 2) {
// ok
} catch Error (string memory reason) {
// returns the string message
// fails to catch if an object is returned
}
}
Docs: https://docs.soliditylang.org/en/v0.8.13/control-structures.html#try-catch
Note that there is a logical error in the second snippet.
// `balance` needs to be lower than `amount`
// otherwise fail
require(balance[msg.sender]<amount, "Insufficient Balance");
should be
// `balance` needs to be larger or equal than `amount`
// otherwise fail
require(balance[msg.sender] => amount, "Insufficient Balance");
In require we specify a condition that, if false, it will revert.
Revert and error is more sophisticated version of the require, where you can specify the condition to depend on the context and create a custom error.
For example
error InvalidAmount (uint256 sent, uint256 minRequired);
contract TestToken {
mapping(address => uint) balances;
uint minRequired;
constructor (uint256 _minRequired) {
minRequired = _minRequired;
}
function list() public payable {
uint256 amount = msg.value;
if (amount < minRequired) {
revert InvalidAmount({
sent: amount,
minRequired: minRequired
});
}
balances[msg.sender] += amount;
}
}
In that code an error called "Invalid amount" is required and it is made to depend on the minimum amount fed in to the constructor. If amount is less than minimum amount, transaction will revert with the custom error which will specify the amount fed by the user and the minimum amount fed in to constructor.
In OpenZeppelin ERC20 implementation, there is a _transfer method:
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
}
Why do they use uncheked arithmetic for decreasing the balance? I know that in case of unchecked, 2-3 will return 2**256-1 and not case an exception. But why do we need this?
unchecked produces smaller bytecode compared to regular arthimetic operations, as it doesn't contain the underflow/overflow validation.
So if you want to have a custom error message in case overflow would occur, this code costs less gas to run
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
// no validation here as it's already validated in the `require()` condition
_balances[sender] = senderBalance - amount;
}
compared to this one
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
// redundant validation here
_balances[sender] = senderBalance - amount;
Without the custom message, this would be the cheapest, but still safe, option:
// contains the check and fails without custom message in case of underflow
_balances[sender] -= amount;
And this would be even cheaper compared to the previous one. But it's unsafe as it doesn't check for undeflow:
unchecked {
// UNSAFE, DO NOT USE
_balances[sender] -= amount;
}
There is sample code in "Modular Contracts" that uses a mapping, but I cannot see where that values of each mapping index get assigned.
The mapping is defined as:
mapping(address => uint256) balances;
and it is passed into the library function "Balances":
library Balances {
function move(mapping(address => uint256) storage balances,
address from,
address to,
uint amount) internal {
require(balances[from] >= amount);
require(balances[to] + amount >= balances[to]);
balances[from] -= amount;
balances[to] += amount;
...
But I don't see where any value is actually initially added to balances in any part of the full code example.
The move function first checks if balances[from] >= amount. At the end of that function you see it adds and subtracts from the identified balances, but that code will never be reached, right? Since require(balances[from] >= amount); will always return false.
What am I missing?
It's just an example of Modular Contracts you can add any balance in your constructor like
constructor() public {
balances[yourAddress] = amount
}
so i was reading through this https://www.ethereum.org/token#minimum-viable-token article which is providing an example for an ethereum token with such functionalities as transferring and burning coins. Lets take a piece of code:
function burn(uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
balanceOf[msg.sender] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
Burn(msg.sender, _value);
return true;
}
everything is pretty clear to me here, we take coins from sender, then take it from the total supply, but what's with line:
Burn(msg.sender, _value);
Where does this function come from? what it does which wasnt done already?
It's publishing an event, declared earlier in the code:
// This notifies clients about the amount burnt
event Burn(address indexed from, uint256 value);
Here's a blog post I wrote about events, including how they're monitored client-side: https://programtheblockchain.com/posts/2018/01/24/logging-and-watching-solidity-events/.