No visibility specified. Defaulting to "public". function transfer(address receiver, uint amount); - ethereum

I am doing a criptoCoin and I am using Solidity. I have an issue when create a crowdsale on function transfer(address receiver, uint amount);
} the compile said No visibility specified. Defaulting to "public".
function transfer(address receiver, uint amount);
^-----------------------------------------------^\

There's nothing necessarily wrong with your code - the compiler is just warning you that you didn't specify a visibility scope, and that it'll be defaulting it to public.
Something like this is probably what you want:
function transfer(address receiver, uint amount) external {}
The external keyword just means that the function can only be called from outside the contract - i.e. by other contracts/addresses on the Ethereum network. Other options include public, private, and internal. You can read more about these visibility keywords here.

Related

Allowance failed when attempting to transfer LINK tokens

I'm creating a smart contract where users can create NFT raffles. I will be using Chainlink VRF for getting provably fair results. For this, the user who creates the raffle needs to supply the contract with LINK tokens. I'm attempting to transfer these tokens using an allowance.
function initRaffle(address _tokenContract, uint256 _tokenId, uint256 _ticketPrice) external {
require(_ticketPrice > 0, "Ticket price must be bigger than 0");
require(LINKToken.balanceOf(msg.sender) >= ChainlinkFee, "Insufficient LINK supplied");
require(LINKToken.allowance(msg.sender, address(this)) >= ChainlinkFee, "Allowance failed");
Running initRaffle results in Allowance failed. I've checked and the LINKToken.balanceOf(msg.sender) is bigger than the fee, so that shouldn't be the problem. The LINKToken.balanceOf(address(this)) is 0.
What's going wrong? And how do I create a working function for having the user transfer (fee amount) link tokens to the contract.
The user needs to invoke approve(yourContractAddress, feeAmount) directly on the LINKToken contract (not through your contract). This sets the allowance.
You can then use transferFrom() to pull tokens (up to the allowed amount) from the user's wallet.
bool success = LINKToken.transferFrom(msg.sender, address(this), ChainlinkFee);

Questions about mint, burn function in UniswapV2Pair.sol

I'm studying UniswapV2Pair.sol https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol and I have some question about the mint and burn function.
What I understand:
When user deposit the token pair, mint function mints the new liquidity token and send to the user
When user withdraw the token pair, burn function burns the new liquidity token and sends the deposited token pair back to user .
What I'm confused about:
I'm confused about the bold part of burn function I mentioned above. I think that mint and burn function is like mirror(opposite) function, but mint function doesn't include the feature which token pair are send to the exchange contract. However, burn function uses _safeTransfer which sends the token pair back to user.
I'm confused why did they designed assymetrically.
The mint() function calculates the amount of minted LP tokens from the difference of
recorded reserves of the underlying tokens (_reserve0 and _reserve1)
and the actual underlying token balance owned by the pair contract (balance0 and balance1)
So theoretically, if Alice just sent the underlying tokens to the pair contract without invoking the mint() function, that would make the accounting difference described above. And Bob would be able to invoke the mint() function and mint the LP tokens for himself profiting off Alice.
But that's not the usual process flow. Usually, the liquidity provider (Alice), invokes the addLiquidity() function of the router contract that performs both actions at once:
transfers the (approved) tokens from the user to the pair contract
invokes the mint() function on the pair contract calculating the difference created in this transaction
Which removes the possibility for Bob to intercept the Alice's minting process.
And having the mint() function executable by itself also allows anyone to claim unclaimed tokens that were sent to the pair contract by mistake for example.
However, if you want to transfer the underlying tokens out of the pair contract (i.e. burn() the LP tokens), there needs to be check already in the burn() function so that you can't claim more of the underlying tokens than you're eligible to.
No matter if you're invoking the pair burn() function directly or from the router removeLiquidity() (that's normally invoked from the Uniswap UI).
but mint function doesn't include the feature which token pair are
send to the exchange contract.
You showed the UniswapV2Pair.sol. mint function is used when we add liquidity which is defined in UniswapV2Router02.sol
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
(amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);
TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
liquidity = IUniswapV2Pair(pair).mint(to);
}
we are passing the amount of tokens that we want to add liquidity, since we cannot add an arbitrary amount, adding liquidity should not affect on the price, so the function itself is calculating the proper amounts and then those amounts are transferred to the UniswapV2Router02 contract. After those amounts are transferred, we are minting a new LP token and sending it to the to address
IUniswapV2Pair(pair).mint(to)
Inside mint function how much token will be minted is calculated and then _mint function called
_mint(to, liquidity);

In OpenZeppelin's implementation of ERC20's transferFrom, why is _transfer() called before withdrawer allowance is checked

This is taken from OpenZeppelin's ERC20 transferFrom implementation:
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), currentAllowance - amount);
return true;
}
Is there a reason why _transfer is called prior to checking the withdrawer (msg.sender) allowance?
Would transferFrom still work correctly if the allowance require check was done first instead?
I found discussion about the same topic on the OpenZeppelin GitHub Issues and the author of the code confirms the order is irrelevant in the context of ERC-20.
In the case of ERC20, the order is irrelevant because _transfer and _approve are independent and never call any other contract: they are executed atomically.
Plus he states it's important to keep the order stabilized for the case when someone wants to override the functions.
However, this is very relevant for users that intent to override _transfer or _approve with their own implementations: we should be clear about the order in which these things happen.
Source: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2030#issuecomment-568487500
So assuming you're not using custom logic in overriden _transfer() and _approve() internal functions, the transferFrom() would still work correctly if you switched the order.
I was actually looking for the same thing, then I found this discussion
[https://forum.openzeppelin.com/t/in-erc20-tranferfrom-why-transfer-before-checking-allowance/5312/3] It gives more details and shed the light on the reasoning behind it.

how to transfer fund from msg.sender(amount) to recipient address without using setting msg.value

We can transfer funds from address(this) to recipient. But is there any way to transfer funds directly msg.sender wallet to recipient? I can not set msg.value at the time of invoking payoutBonus call. Because I can get the amount only inside payoutBonus method.
function payoutBonus(address recipient) public payable returns (bool) {
// bonus = calculateBonus();
//transfer this bonus to recipient from msg.sender;
return true;
}
msg.value is a read-only property reflecting value of the incoming transaction. If you want to send an ETH amount, you can do it in one of two ways.
Notes:
These examples work on Solidity 0.8. Some previous versions also allow the send() method that is now deprecated, don't require the payable type, and have slightly different syntax for the call() method.
bonus is amount of wei (1 ETH is 10^18 wei)
The transfer() method
uint256 bonus = calculateBonus();
payable(msg.sender).transfer(bonus);
The transfer() method only allows consuming 2300 gas, which is enough for non-contract recipients. If the recipient is a contract requiring more than 2300 gas to receive the ETH (for instance it sets some local variable), the transaction reverts.
Low-level call()
uint256 bonus = calculateBonus();
msg.sender.call{value: bonus}("");
With the low-level call() method, you can also specify the gas limit, function to call and it's arguments. Use this method only if you know what you're doing.

Can one contract own tokens of another one

if I got it right smart contracts do not have a private key, so they can not sign transactions. The first transaction is signed buy the user and if a contract calls another contract and so on, those transactions are also signed buy the user. So, what if we have two ERC20 contracts A and B and B holds some A tokens.
contract A{
....
//balance of contract B
balanceOf[0xE4e5a16C8fx207a07f7df98e3a85e2067feacB9w]=500;
function transfer(address _to, uint256 _value) public {
_transfer(msg.sender, _to, _value);
}
....
}
contract B{
//address this=0xE4e5a16C8fx207a07f7df98e3a85e2067feacB9w
}
What if some user pretend to to be a contract B calling contract A?
I mean he will sign the sequence of transactions where the last one would not come from the contract B, but contract A will think so.
It will look like this:
{
data: "0xa9059cbb000000000000000000000000cf2ee9c0dccd39aac2fd44b744270f50f8af13b00000000000000000000000000000000000000000000000000000000000000064",
from: "0xE4e5a16C8fx207a07f7df98e3a85e2067feacB9w ",//address B
gas: 210000,
gasPrice: 1,
nonce: "24",
to: "0xa6d90569018967c5esc7d056f74eg4hc3j8ae93" //address A
}
If he do so, it is possible for him, using function transfer in contract A and passing in it his own address to steal tokens from contract B balance in contract A.
So am I right and this is really possible or I made a mistake somewhere? And if it is possible, how in this case a contract can own tokens of other contracts?
Yes, contracts can own tokens.
The transaction you specified won't work; you can't just pick a from address. A transaction is sent from an externally owned account (EOA), meaning an account that has a private key. And only the person with that private key can sign such a transaction. See if this blog post helps: https://programtheblockchain.com/posts/2017/12/29/how-ethereum-transactions-work/.
I think I found an answer to my question.
A first person, who signs a sequence of messages can not cheat and substitute the second message, because when nodes will validate his actions they will all run this sequence of messages on their EVM and if the second message is not valid(i.e it is not coming from the contract) the state will not change.