Last active
November 23, 2019 18:12
-
-
Save probablyangg/1c5e1eae196261d52e0e0f433e8113bb to your computer and use it in GitHub Desktop.
The three contracts used to enable PoS enabled asset deposit and withdraw from Matic chain. Manager contract emits events `deposit` and `withdraw`, the bridge listens to these events and invokes relevant functions on RootToken and ChildToken, depending upon the request. Both Deposits and Transfers start from `Manager` contract. There will be a s…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.11; | |
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol"; | |
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; | |
contract ChildToken is ERC20, ERC20Detailed { | |
constructor ( | |
string memory _name, | |
string memory _symbol, | |
uint8 _decimals | |
) public | |
ERC20Detailed(_name, _symbol, _decimals) {} | |
// function caller gets specified amount of tokens | |
function mintTokens (uint256 amount) public { | |
_mint (msg.sender, amount); | |
} | |
// invoked by bridge | |
// mints tokens to user's account | |
function deposit(address user, uint256 amount) public { | |
// check for amount and user | |
require(amount > 0 && user != address(0x0)); | |
_mint(user, amount); | |
} | |
// invoked by bridge | |
// burns tokens | |
function withdraw(address user, uint256 amount) public { | |
require(amount > 0 && user != address(0x0)); | |
_burn(user, amount); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.11; | |
// import { SafeMath } from "github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol"; | |
import './RootToken.sol'; | |
contract Manager { | |
// using SafeMath for uint256; | |
address internal _rootToken; | |
bool deposited; | |
event Deposit ( | |
address user, // user invoking deposit | |
uint256 amountOrTokenId // amount of token to be deposited | |
); | |
event Withdraw ( | |
address user, | |
uint256 amountOrTokenId, // amount of token to be withdrawn | |
bool deposited | |
); | |
constructor(address rootToken) public { | |
_rootToken = rootToken; | |
} | |
function updateRootToken (address newRoot) public { | |
_rootToken = newRoot; | |
} | |
// owned token amount of an address | |
mapping (address => uint256) public ownedTokens; | |
// emits deposit event | |
// bridge listens this event and invokes `deposit` in childtoken | |
function deposit (uint256 _tokenAmt) public { | |
ownedTokens[msg.sender] += _tokenAmt; | |
RootToken(_rootToken).transferFrom(msg.sender, address(this), _tokenAmt); // manager contract has to be approved from the user | |
emit Deposit (msg.sender, _tokenAmt); | |
} | |
// emits withdraw event | |
// bridge listens this event and invokes withdraw in childtoken (burn on child) | |
// and if deposited = false => invokes withdraw in roottoken | |
function withdraw (uint256 _tokenAmt) public { | |
if (ownedTokens[msg.sender] != 0) { | |
// the token was deposited | |
deposited = true; | |
require (_tokenAmt <= ownedTokens[msg.sender], | |
"trying to withdraw more than what was deposited by the user"); | |
RootToken(_rootToken).transfer(msg.sender, _tokenAmt); | |
ownedTokens[msg.sender] -= _tokenAmt; | |
emit Withdraw(msg.sender, _tokenAmt, deposited); // burns on child | |
} else { | |
deposited = false; | |
emit Withdraw(msg.sender, _tokenAmt, deposited); // burns on child and mints on root | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.11; | |
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol"; | |
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; | |
contract RootToken is ERC20, ERC20Detailed { | |
constructor ( | |
string memory _name, | |
string memory _symbol, | |
uint8 _decimals | |
) public | |
ERC20Detailed(_name, _symbol, _decimals) {} | |
// function caller gets specified amount of tokens | |
function mintTokens (uint256 amount) public { | |
_mint (msg.sender, amount); | |
} | |
// invoked by bridge for tokens that were minted on child chain | |
function withdraw(address user, uint256 amount) public { | |
_mint(user, amount); | |
} | |
} |
Not sure what is the best way to go for withdrawals
if user invokes withdrawal from rootchain contract, there is no proof of their balance on child chain until an event is emitted and bridge invokes a burn on child, and in case that was a malicious transaction, the tokens would have already been transferred
easier way would be to initiate withdrawal from child chain, but then there would need to be two bridges listening on both networks ..
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Alternative for deposits:
bridge listens to
Transfer
event with recipient as Manager contract's address and mints on child(wont require prior approval)
user simply transfers to Manager smart contract, and the token is minted on child
(possible when dealing with only one pair of contracts - (root, child))