Auto Liquidity Pool Withdraw LP Token from 0x0000
I have a contract at the following:
https://bscscan.com/token/0x5f1b95784a033cd6842cf26eb9a9687f91ad9e78
It got a function which does the following
function swapAndLiquify(uint256 tokens) private {
// split the contract balance into halves
uint256 half = tokens.div(2);
uint256 otherHalf = tokens.sub(half);
// capture the contract's current ETH balance.
// this is so that we can capture exactly the amount of ETH that the
// swap creates, and not make the liquidity event include any ETH that
// has been manually sent to the contract
uint256 initialBalance = address(this).balance;
// swap tokens for ETH
swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered
// how much ETH did we just swap into?
uint256 newBalance = address(this).balance.sub(initialBalance);
// add liquidity to uniswap
addLiquidity(otherHalf, newBalance);
emit SwapAndLiquify(half, newBalance, otherHalf);
}
To date, it controlled 19% of the liquidity token at address 0x00000000000000000 and I was wondering how to withdraw or transfer the Liquidity Token to the contract owner which is my account.
https://bscscan.com/token/0x2f308f3c6994fc1ed690a318f07d67564dcc5aab#balances
Thanks
Related
In below function, how the contract balance is updated by just assigning the msg.value into deposit parameterized variable?
function transferToContract(uint256 deposit) public payable {
require(msg.value == deposit);
deposit = msg.value; //how it works?
}
I'm trying to find answer about behind the mechanics of the above code.And I'm expecting the precise and to the point answer of this.
SInce your function is marked as payable you can send money when you call this function. If you develop an app on Remix, after you deploy the contract, you would have an inbox next to the function to enter the amount. Or if you are interacting with the contract on front-end, you might have a function like this
await contract.methods.contribute().send({
from: accounts[0],
value:1000000,
});
the value that you are sending to the contract will be available to the contract as msg.value.
I am trying to implement a simple token transfer to a Vault but I'm having trouble approving the transaction and when I run tests using foundry, I receive this error:
[FAIL. Reason: ERC20: transfer amount exceeds allowance] testDeposit() (gas: 86770)
My code is for the deposit function is here:
function deposit(uint256 amount) external {
console.log("RANDOM inside deposit = ");
console.log(IERC20(underlyingToken).balanceOf(msg.sender));
console.log("msg sender =");
console.log(msg.sender);
console.log("approve = ");
console.log(IERC20(underlyingToken).approve(address(this), amount));
// IERC20(underlyingToken).approve(msg.sender, amount);
console.log("RANDOM inside deposit after approve = ");
console.log(IERC20(underlyingToken).allowance(msg.sender, address(this)));
IERC20(underlyingToken).transferFrom(msg.sender, address(this), amount);
// // totalDeposited += amount;
IPool(aavePool).supply(underlyingToken, amount, address(this), 0);
totalUnderlyingDeposited += amount;
}
Thank you for the help in advance
You can't have the vault give itself an allowance for the sender. That would defeat the whole point of the approval mechanism.
What your code IERC20(underlyingToken).approve(address(this), amount) actually does is give the vault permission to transfer any of its own tokens using transferFrom. Obviously this is a bit silly since the vault can just use transfer to do that.
Your commented-out code // IERC20(underlyingToken).approve(msg.sender, amount);, as you probably figured out, lets the sender transfer the vault's tokens.
The only way to let the vault do transferFrom(msg.sender, ..., ...) is if the sender interacts directly with the ERC20 by calling approve him/herself.
This means the user will need to do two transactions to do the first deposit into the vault: 1) approve the vault for an allowance sufficient to cover the deposit 2) do the deposit.
If the approval is for an "infinite" amount (max uint256), then subsequent deposits only require a single transaction each; however, this is not considered wise from a security standpoint.
so I created a token tokenA
contract tokenA is ERC20 {
address public deployer; //to save adress of the deployer
constructor() ERC20('tokenA', 'TA') { //called by the deployer (once)
_mint(msg.sender, 1000000000000 * 10 ** 10); //mint/create tokens - we have created 100000000000*10^18 tokens
deployer = msg.sender; //set the deployer
}
//total supply is fixed no more can be created ever
function burn (uint amount) external { //remove tokens by sending then to a zero address
_burn(msg.sender, amount);
}
}
and I have deployed them onto the Rinkeby (4) injected web3 environment.
now I have to use these tokens as price for purchasing an NFT (which I also have to make)
so how do I use them in my code?
I can use ether like
uint price = 0.005 ether;
and the compare the transferred value with this, but if I write
uint price = 0.005 tokenA;
it gives an error, even though I have deployed tokenA and it resides in my meta mask acc
uint price = 0.005 ether; this is correct.
But inside your function to buy an NFT you need:
Remove the payable keyword.
Add the transferFrom function of the ERC-20 token in order to transfer price (0.005e18) tokens to the recipient address you specify.
Keep in mind that in order to successfully call the transferFrom function the user first need to call the approve function.
For a more in dept explanation i suggest to read the OpenZeppelin ERC-20 docs/github repo
I came across this answer while researching creating a function for someone to buy an NFT:
https://stackoverflow.com/a/67384225/1414721
The relevant lines are
IERC20 tokenContract = IERC20(tokenAddress);
require(tokenContract.transferFrom(msg.sender, address(this), price),
"buy: payment failed");
I don't want people to be able to buy my NFTs in anything other than Ethereum, although the author here says:
prevent an edge case where if gas runs out during execution, the buyer could end up with their NFT for free
This caught my eye and from reading the code it seems the check that is being done here is to prevent this edge case.
What I'm not sure of is how the applies when the currency the NFT is being bought in is Ethereum.
I have adjusted my buy function to look like
function buy(uint256 _tokenId) external payable {
uint256 price = tokenIdToPrice[_tokenId];
require(price > 0, 'This token is not for sale');
require(msg.value == price, 'Incorrect value');
address seller = ownerOf(_tokenId);
IERC20 tokenContract = IERC20(address(0));
require(tokenContract.transferFrom(msg.sender, address(this), price), "buy: payment failed");
payable(seller).transfer(msg.value);
_transfer(seller, msg.sender, _tokenId);
tokenIdToPrice[_tokenId] = 0;
emit NftBought(seller, msg.sender, msg.value);
}
which I believe a) incorporates the token Contract from being the Ethereum token (IERC20(address(0)) - I understand address(0) is the Ethereum token address?) and b
require(tokenContract.transferFrom(msg.sender, address(this), price), "buy: payment failed");
makes sure the gas limit edge case mentioned is handled.
Is this correct, Googling this was quite hard.
One last question (unrelated, I hope that's OK) - when a market displays all the NFTs available for a collection, i assume that the way they are doing that is the contract has a function that returns the NFT IDs and the Token URIs? Is that correct, or does OpenZeppelin provide this functionality and I don't have to concern myself with adding this function?
i think the gas edge case was solved by changing the order of operations. first pay then transfer the token.
Exploring blockchain using Ethereum and solidity via Remix and I encounter this code:
pragma solidity ^0.8.1;
contract AccountsDemo{
address public whoDeposited;
uint public depositAmt;
uint public accountBalance;
function deposit() public payable{
whoDeposited = msg.sender;
depositAmt = msg.value;
accountBalance += address(this).balance
}
}
According to the book I'm using, calling deposit should result in accountBalance and depositAmt being increased. When I try, nothing happens. The transactions are recorded on the blockchain but no increase happens. The book uses an older version of solidity - 0.6.0 not sure if this is the cause of my frustration.
Any idea what I'm missing here?
What your current deposit function does:
whoDeposited = msg.sender;
Stores the sender address to property whoDeposited. Mind that the value of whoDeposited is overwritten every time you execute the deposit() function.
depositAmt = msg.value;
Stores the transaction value to property depositAmt. Mind that the value of depositAmt is overwritten every time you execute the deposit() function.
accountBalance += address(this).balance
Increments value of property accountBalance by current contract balance. The current contract balance (address(this).balance) already reflects the transaction value that was send while executing the deposit() function.
So if your contract already had balance of 10 wei, accountBalance was 10, and now you were sending 2 wei... During the execution, address(this).balance is now 12 (because of the 2 wei that you're sending), and then accountBalance += 12, which is a result you don't want.
By the way, your snippet has a syntax error and it wouldn't compile because of the missing semicolon at the end of line.
To achieve your goal - store the current contract balance in both depositAmt and accountBalance (so they are always going to have the same value, also same as address(this).balance), you can do this:
depositAmt += msg.value;
accountBalance = address(this).balance;
I switched the += and = operators. So now, when you send a value to your deposit() function:
whoDeposited = msg.sender;
The behavior stays the same as described above.
depositAmt += msg.value;
Every time you execute the deposit() function, the value of depositAmt increments by the value of the transaction. Which effectively reflects the current balance of your contract.
accountBalance = address(this).balance;
Every time you execute the deposit() function, the value of accountBalance is set to the current contract balance. The current contract balance already reflects the value you sent in the current transaction.
Note: I used the word "always" few times in this answer. It's not really always - there are some edge cases like funding your contract address from a selfdestruct function or prior to the contract deployment, where the address(this).balance is going to be different from your depositAmt and accountBalance. But most likely, you're not going to meet these edge cases in the beginning, so you can consider it "always" for now. It's just good to know that there are cases where this snippet won't work as expected.