Skip to content

Commit

Permalink
Merge pull request #6 from bttcprotocol/add_token_for_exchange
Browse files Browse the repository at this point in the history
add token exchange template
  • Loading branch information
tomatoishealthy authored Feb 14, 2022
2 parents 60f8af5 + bfd3e31 commit 674dd0d
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions contracts/child/ChildToken/ChildERC20ForExchange.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
pragma solidity 0.6.6;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {AccessControlMixin} from "../../common/AccessControlMixin.sol";
import {IChildToken} from "./IChildToken.sol";
import {NativeMetaTransaction} from "../../common/NativeMetaTransaction.sol";
import {ContextMixin} from "../../common/ContextMixin.sol";


contract ChildERC20ForExchange is
ERC20,
IChildToken,
AccessControlMixin,
NativeMetaTransaction,
ContextMixin
{
event SwapIn(address indexed sender, uint256 value);
event SwapOut(address indexed sender, uint256 value);

bytes32 public constant DEPOSITOR_ROLE = keccak256("DEPOSITOR_ROLE");

address public immutable originToken;

constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
address childChainManager,
address origin_
) public ERC20(name_, symbol_) {
_setupContractId("ChildERC20ForExchange");
_setupDecimals(decimals_);
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(DEPOSITOR_ROLE, childChainManager);
_initializeEIP712(name_);
originToken = origin_;
}

// 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));
_mint(user, amount);
}

/**
* @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 withdrawTo(address to, uint256 amount) public {
_burn(_msgSender(), amount);
emit WithdrawTo(to, address(0x00), amount);
}

function withdraw(uint256 amount) external {
withdrawTo(_msgSender(), amount);
}

function swapIn(uint256 amount) public {
require(originToken != address(0x0), "origin token not set");
IERC20(originToken).transferFrom(_msgSender(), address(this), amount);
_mint(_msgSender(), amount);
emit SwapIn(_msgSender(), amount);
}

function swapOut(uint256 amount) public {
require(originToken != address(0x0), "origin token not set");
_burn(_msgSender(), amount);
IERC20(originToken).transfer(_msgSender(), amount);
emit SwapOut(_msgSender(), amount);
}

}

0 comments on commit 674dd0d

Please sign in to comment.