Last active
March 15, 2022 21:37
-
-
Save cagodoy/53fbfd5c954f460675fe34c2136de032 to your computer and use it in GitHub Desktop.
Bridge example implementaton
This file contains hidden or 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
| // SPDX-License-Identifier: MIT | |
| pragma solidity ^0.8.2; | |
| import "@openzeppelin/contracts/access/Ownable.sol"; | |
| import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | |
| import "hardhat/console.sol"; | |
| interface IERC20WithMintAndBurn is IERC20 { | |
| function mint(address to, uint256 amount) external; | |
| function burn(address to, uint256 amount) external; | |
| } | |
| contract Bridge is Ownable { | |
| IERC20WithMintAndBurn public token; | |
| enum TransactionKind { | |
| INBOUND, | |
| OUTBOUND | |
| } | |
| enum TransactionStatus { | |
| CREATING, | |
| MINTING, | |
| READY, | |
| FAILED | |
| } | |
| struct transaction { | |
| uint256 count; | |
| address from; | |
| address to; | |
| uint256 amount; | |
| TransactionStatus status; | |
| } | |
| mapping(uint256 => transaction) private inboundTransactions; | |
| mapping(uint256 => transaction) private outboundTransactions; | |
| uint256 public outboundCount = 0; | |
| uint256 public inboundCount = 0; | |
| event Transaction( | |
| uint8 kind, | |
| uint256 count, | |
| address from, | |
| address to, | |
| uint256 amount, | |
| uint8 status | |
| ); | |
| constructor(address _token) { | |
| token = IERC20WithMintAndBurn(_token); | |
| } | |
| function getInboundTransactions(uint256 _count) | |
| external | |
| view | |
| returns ( | |
| uint256, | |
| address, | |
| address, | |
| uint256, | |
| uint8 | |
| ) | |
| { | |
| transaction memory t = inboundTransactions[_count]; | |
| return (t.count, t.from, t.to, t.amount, uint8(t.status)); | |
| } | |
| function getOutboundTransactions(uint256 _count) | |
| external | |
| view | |
| returns ( | |
| uint256, | |
| address, | |
| address, | |
| uint256, | |
| uint8 | |
| ) | |
| { | |
| transaction memory t = outboundTransactions[_count]; | |
| return (t.count, t.from, t.to, t.amount, uint8(t.status)); | |
| } | |
| function outbound(address to, uint256 amount) external { | |
| // get current balance using balanceOf method from ERC20 contract | |
| uint256 balance = token.balanceOf(msg.sender); | |
| // check if balance is enough | |
| require(balance >= amount, "the current balance is not enough"); | |
| // burn current tokens | |
| token.burn(msg.sender, amount); | |
| transaction storage t = outboundTransactions[outboundCount]; | |
| t.count = outboundCount; | |
| t.from = msg.sender; | |
| t.to = to; | |
| t.amount = amount; | |
| t.status = TransactionStatus.MINTING; | |
| emit Transaction( | |
| uint8(TransactionKind.OUTBOUND), | |
| outboundCount, | |
| msg.sender, | |
| to, | |
| amount, | |
| uint8(t.status) | |
| ); | |
| // set next counter to outbound | |
| outboundCount++; | |
| } | |
| function inbound( | |
| uint256 _inboundCount, | |
| address to, | |
| uint256 amount | |
| ) external onlyOwner { | |
| // get transaction by count | |
| transaction storage t = inboundTransactions[_inboundCount]; | |
| // check if transaction status is valid | |
| require(t.status != TransactionStatus.READY, "transaction done"); | |
| require( | |
| t.status != TransactionStatus.MINTING, | |
| "transaction has invalid status" | |
| ); | |
| // minting tokens | |
| token.mint(to, amount); | |
| // update the transaction | |
| t.count = _inboundCount; | |
| t.from = msg.sender; | |
| t.to = to; | |
| t.amount = amount; | |
| t.status = TransactionStatus.READY; | |
| // emit transaction event after for minting tokens | |
| emit Transaction( | |
| uint8(TransactionKind.INBOUND), | |
| _inboundCount, | |
| msg.sender, | |
| to, | |
| amount, | |
| uint8(t.status) | |
| ); | |
| // set next counter to inbound | |
| inboundCount++; | |
| } | |
| function done(uint256 _outboundCount, TransactionStatus status) | |
| external | |
| onlyOwner | |
| { | |
| // get transaction by count | |
| transaction storage t = outboundTransactions[_outboundCount]; | |
| // check if transaction is valid | |
| require( | |
| t.from != address(0) || t.to != address(0), | |
| "transaction not found" | |
| ); | |
| // check if outbound transaction status is valid | |
| require( | |
| !(t.status == TransactionStatus.READY || | |
| t.status == TransactionStatus.FAILED), | |
| "transaction done" | |
| ); | |
| // check if transaction status param is valid | |
| require( | |
| status == TransactionStatus.READY || | |
| status == TransactionStatus.FAILED, | |
| "invalid status" | |
| ); | |
| // update status | |
| t.status = status; | |
| // emit transaction event after for minting tokens | |
| emit Transaction( | |
| uint8(TransactionKind.OUTBOUND), | |
| _outboundCount, | |
| t.from, | |
| t.to, | |
| t.amount, | |
| uint8(t.status) | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment