Skip to content

Instantly share code, notes, and snippets.

@itzmeanjan
Last active July 6, 2021 06:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itzmeanjan/02b18ed506c5fb0788992009308a3c5f to your computer and use it in GitHub Desktop.
Save itzmeanjan/02b18ed506c5fb0788992009308a3c5f to your computer and use it in GitHub Desktop.
An illustration of sending data from Ethereum root chain to Matic child chain
// File: contracts/child/ChildToken/ChildERC20.sol
pragma solidity 0.6.6;
contract ChildERC20 is
ERC20,
IChildToken,
AccessControlMixin,
NativeMetaTransaction,
ChainConstants,
ContextMixin
{
bytes32 public constant DEPOSITOR_ROLE = keccak256("DEPOSITOR_ROLE");
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
address childChainManager
) public ERC20(name_, symbol_) {
_setupContractId("ChildERC20");
_setupDecimals(decimals_);
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(DEPOSITOR_ROLE, childChainManager);
_initializeEIP712(name_, ERC712_VERSION);
}
// This is to support Native meta transactions
// never use msg.sender directly, use _msgSender() instead
function _msgSender()
internal
override
view
returns (address payable sender)
{
return ContextMixin.msgSender();
}
/**
* @notice called when token is deposited on root chain
* @dev Should be callable only by ChildChainManager
* Should handle deposit by minting the required amount for user
* Make sure minting is done only by this function
* @param user user address for whom deposit is being done
* @param depositData abi encoded amount
*/
function deposit(address user, bytes calldata depositData)
external
override
only(DEPOSITOR_ROLE)
{
uint256 amount = abi.decode(depositData, (uint256));
// tokens minted on child chain for `user`
_mint(user, amount);
// this is not the only way of doing it, using low level call here
// this might be little overengineering for this given scenario
(bool success, bytes memory result) = address(this).call(abi.encodeWithSignature("callback(address,uint256)", user, amount));
// or as we know function to be called in this contract, we can do another thing
// given `callback` function is predefined for child chain contract
// where we can also emit some event which can be caught, offchain
callback(user, amount);
}
function callback(address user, uint256 amount) internal {
// doing nothing useful here, as of now
// but you can always implement custom logic here, which is to be executed
// whenever any token deposit is performed from root to child
}
/**
* @notice called when user wants to withdraw tokens back to root chain
* @dev Should burn user's tokens. This transaction will be verified when exiting on root chain
* @param amount amount of tokens to withdraw
*/
function withdraw(uint256 amount) external {
_burn(_msgSender(), amount);
}
}
@hack3r-0m
Copy link

hack3r-0m commented Mar 21, 2021

@itzmeanjan is it onStateReceived or onStateReceive (without d) or both works? because I have seen few contracts on matic-pos-portal with the latter one

@mahendran216
Copy link

What is the use of that function _msgSender() in line 30??
Can someone please explain the working of that function??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment