How to get the amount of token sent to a smart contract via the fallback function in solidity - token

Let's say I have a token A and a smart contract B.
A user sent some amount of A to to the contract B by direct transfer through his wallet.
In the fallback function of the smart contract B, how will I get the amount of token A that was sent?
msg.value did'nt give me anything since it's not Eth that was sent.

When your contract receives ERC-20 tokens, the fallback() function is not invoked - nor any other function. Meaning, your contract does not get notified about incoming ERC-20 transfers unless you pull them with transferFrom().
contract YourContract {
function pullTokens() external {
// need to have prior approval
tokenContract.transferFrom(msg.sender, address(this), amount);
}
}
Note: Some other fungible token standards define these notification functions for recipient contracts - for example ERC-777 and its function tokensReceived().

Related

Send a NFT together with Tokens

Is there a way to send an 1155 or 731 nft in one transaction together with a token(erc-20)
and if yes could someone provide an example
You can create a muticall contract that wraps both token transfers into one transaction.
Example:
pragma solidity ^0.8;
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
import "#openzeppelin/contracts/token/ERC721/IERC721.sol";
contract MyContract {
IERC20 erc20Token = IERC20(address(0x123));
IERC721 nftCollection = IERC721(address(0x456));
function sendFromThisContract(address to, uint256 erc20Amount, uint256 nftId) external {
erc20Token.transfer(to, erc20Amount);
nftCollection.transferFrom(address(this), to, nftId);
}
function sendFromUser(address to, uint256 erc20Amount, uint256 nftId) external {
erc20Token.transferFrom(msg.sender, to, erc20Amount);
nftCollection.transferFrom(msg.sender, to, nftId);
}
}
In case of sendFromUser(), the user needs to send additional 2 transactions to be able to perform this action:
to the ERC20 token contract, approving MyContract to operate the user's tokens
to the NFT collection contract, approving MyContract to operate the user's specific token ID (or all tokens)
It is not technically possible to transfer multiple tokens (with different contract addresses) in one transaction without an intermediary or without the approvals. This is because when you're sending a token, you're sending a transaction to the token/collection contract. And by design, a transaction can have only one recipient.

How to add tokenomics to a ERC20 token?

I have taken different courses and even tho they explain how to make a token I haven't been able to learn how to implement tokenomics.
For example fees for transactions, burning to LP etc...
I leave a link to the openzeppelin standard
Would be great to have some more detailed examples on it.
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol
What you are looking for is to make a custom _transfer() method by overriding the one provided in the OpenZeppelin ERC20 standard.
You can check with the "OXB" (oxbull.tech) token, which implements this type of fee, but basically you just take tokens from the sender before sending them to the receiver, and once you are done charging the fees you can send the remaining tokens to the receiver.
An example would be:
function _transfer(address sender, address recipient, uint256 amount) private {
require(sender != address(0), "BEP20: transfer from the zero address");
require(balanceOf(sender) >= amount, "BEP2': not enough balance");
uint256 tokensToBurn = amount.mul(burningFee).div(100);
amount = amount.sub(tokensToBurn);
balances[sender] = balances[sender].sub(amount);
_burn(sender, tokensToBurn);
balances[recipient] = balances[recipient].add(amount);
}
Options of what you can do are infinite. Hope this is helpful.

Where do the ethers come from when sending ethers with .send() function in ethereum contract

I'm learning ethereum token contract following here. I'm confused by the code below:
function sell(uint amount) returns (uint revenue){
if (balanceOf[msg.sender] < amount ) throw; // checks if the sender has enough to sell
balanceOf[this] += amount; // adds the amount to owner's balance
balanceOf[msg.sender] -= amount; // subtracts the amount from seller's balance
revenue = amount * sellPrice;
if (!msg.sender.send(revenue)) { // sends ether to the seller: it's important
throw; // to do this last to prevent recursion attacks
} else {
Transfer(msg.sender, this, amount); // executes an event reflecting on the change
return revenue; // ends function and returns
}
}
the line msg.sender.send(revenue) means to send ethers to the seller. My question is:
Does the ethers to be sent come from msg.sender or from the token contract?
I think they comes from msg.sender. However the msg.sender is actually in behalf of the seller, right? That makes the seller sends himself ethers. May I know how to understand this. And then how do I make a contract send ethers back to a user account automatically?
Thanks!
I did some tests to figure out this question. I find out that the ethers which are sent to destination address are from the token contract instance address.
I was confused before because I didn't understand how a contract instance gains ethers after being constructed. Now I get to know that the contract instance gains ethers when an account invokes a method marked by keyword payable of the contract. When the invoking happens the ethers are sent to the contract address at the meantime. In the demo token code, it is the method buy() who plays the role to send ethers to the contract address.
I'm new for learning ethereum contract. There probably still are some mistakes about what I realize. Please let me know if there are. Appreciate that!
Thanks!
.send is a function belonging to the address type, where the address on which it's called is the recipient. The ETH being sent comes from the smart contract.
You can also use transfer and call. This article does a good job of explaining the differences.
Examples:
address recipient = 0x0000000000000000000000000000000000000000;
// using transfer
recipient.transfer(revenue);
// using call
recipient.call{value: revenue}("");

Get related subscribed channel(s) in didReceiveStatus in PubNub for iOS objective C

When didReceiveStatus is called after subscribing to a channel, We are not able to retrieve the channel(s) that was just subscribed.
PNSubscribeStatus.data.subscribedChannel or PNSubscribeStatus.data.actualChannel are always null and PNSubscribeStatus.subscribedChannels gives all currently subscribed channels and not the ones that triggered the didReceiveStatus callback.
What are we doing wrong here ?
In SDK 4.0, didReceiveStatus returns a PNStatus, which according to the class documentation doesn't contain that extra information unless there's an error condition. For our application, we use that handler to monitor connection status to the PubNub server.
PubNub Message Received Channel Name in iOS
You should be able to get the channel that you received the message on but getting it depends on whether you are subscribed to the channel or to a channel group that contains the channel. This is sample code from the PubNub Objective-C for iOS SDK subscribe API Reference:
- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
// Handle new message stored in message.data.message
if (message.data.actualChannel) {
// Message has been received on channel group stored in
// message.data.subscribedChannel
}
else {
// Message has been received on channel stored in
// message.data.subscribedChannel
}
NSLog(#"Received message: %# on channel %# at %#", message.data.message,
message.data.subscribedChannel, message.data.timetoken);
}
If you need other channels that the client is subscribed to, you can call the where-now API.
If you need to be more dynamic about what the reply-to channel should be, then just include that channel name in the message when it is published, assuming the publisher has prior knowledge about which channel this is. Or you can do a just in time lookup on your server as to which channel to reply to.
Here is PubNub support answer on this :
Actually status.data.subscribedChannel and status.data.actualChannel
dedicated to presence events and messages receiving callbacks where
information about sources of event is important.
In -client:didReceiveStatus: client doesn’t give information about
particular channel on which client has been subscribed. If client will
start track this information, there is no guarantee what it will
return expected value (as developer expect some channels to be there).
In previous version (3.x) all this information has been tracked, but
because it can be modified at any moment – result sometimes was
unpredictable.
Subscribe can be done in sequence of methods (one after another) like:
subscribe A1, subscribe C1, subscribe B1 and B2, unsubscribe C1 and B1
– this as result will end up with single call of
-client:didReceiveStatus: with resulting set of channels.
It always best practice just to check whether your channels is in
s_tatus.subscribedChannels_.
My comments:
The point of having asynchronous process is exactly not to think this as sequence of methods... We can not have the guaranty that subscriptions are done in the exact same order as the subscription request unless we block other subscription request until the previous one is done.

What is the cryptogram in the ApplePay token?

I'm currently working on ApplePay and we are decrypting the token on our own server.
The decryption of token is done but there is a few things I don't quite understand. From the Getting-Started-with-Apple-Pay we know that:
"The payment token encapsulates the
information needed to complete a payment
transaction, including the device-specific
account number, the amount, and a unique,
one-time-use cryptogram."
But from the Payment Token Format Reference, there are 8 things contained in a token:
applicationPrimaryAccountNumber
applicationExpirationDate
currencyCode
transactionAmount
cardholderName
deviceManufacturerIdentifier
paymentDataType
paymentData
We get the accountNumber and the amount, but which one of those is the cryptogram?
Is it the last one, paymentData, since the other 7 really don't look like cryptogram? If not, how could we get this cryptogram?
I'd also like to ask what should we do after we get the cryptogram? Should we send the cryptogram and accountNumber to the acquirer?
Thank you!
If you look at the Payment Token Format
You will see that the token contains a paymentDataType string and a paymentData dictionary.
If the paymentDataType is "3DSecure" then the paymentData dictionary will contain a key onlinePaymentCryptogram which is the cryptogram string.
This must be submitted to your payment gateway if you are submitting a 3-D Secure transaction.

Resources