-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2b0247e
commit ef40313
Showing
2 changed files
with
148 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity >=0.8.0 <0.9.0; | ||
|
||
/** | ||
* Layer exchange oracle. | ||
*/ | ||
interface L2 | ||
{ | ||
/** | ||
* Burns the layer-2 coins that should be unlocked on the layer-1 blockchain. | ||
* | ||
* @param account the account to debit. | ||
* @param amount the amount to burn. | ||
*/ | ||
function burn(address account, uint256 amount) external; | ||
|
||
/** | ||
* Mints the layer-2 coins that have been locked on the layer-1 blockchain. | ||
* | ||
* @param account the account to credit. | ||
* @param amount the amount to mint. | ||
*/ | ||
function mint(address account, uint256 amount) external; | ||
} | ||
|
||
/** | ||
* Layer-1 contract. | ||
*/ | ||
contract Layer1 | ||
{ | ||
/** | ||
* Layer-2 oracle. | ||
*/ | ||
L2 public l2; | ||
|
||
/** | ||
* Creates a new contract. | ||
* | ||
* @param l2_ the layer-2 exchange oracle. | ||
*/ | ||
constructor(L2 l2_) | ||
{ | ||
l2 = l2_; | ||
} | ||
|
||
/** | ||
* Locks the layer-1 coins and mints the same amount on the layer-2 blockchain. | ||
*/ | ||
function lock() external payable | ||
{ | ||
require(address(l2) != address(0), "layer-2 oracle must be set"); | ||
l2.mint(tx.origin, msg.value); | ||
} | ||
|
||
/** | ||
* Unlocks the layer-1 coins by burning the same amount on the layer-2 blockchain. | ||
* | ||
* @param amount the amount to redeem. | ||
*/ | ||
function unlock(uint256 amount) external | ||
{ | ||
require(address(l2) != address(0), "layer-2 oracle must be set"); | ||
l2.burn(tx.origin, amount); | ||
payable(tx.origin).transfer(amount); | ||
} | ||
} | ||
|
||
/** | ||
* Layer-2 contract. | ||
*/ | ||
contract Layer2 is L2 | ||
{ | ||
/** | ||
* Address balances. | ||
*/ | ||
mapping(address => uint256) public balance; | ||
|
||
/** | ||
* Contract owner. | ||
*/ | ||
address public owner; | ||
|
||
/** | ||
* Creates a new contract. | ||
* | ||
* @param owner_ the contract owner. | ||
*/ | ||
constructor(address owner_) | ||
{ | ||
owner = owner_; | ||
} | ||
|
||
function burn(address account, uint256 amount) external | ||
{ | ||
require(msg.sender == owner, "must be called by contract owner"); | ||
require(amount >= balance[account], "insufficient balance"); | ||
balance[account] -= amount; | ||
} | ||
|
||
function mint(address account, uint256 amount) external | ||
{ | ||
require(msg.sender == owner, "must be called by contract owner"); | ||
balance[account] += amount; | ||
} | ||
|
||
/** | ||
* Sets the contract owner. | ||
* | ||
* @param owner_ the new contract owner. | ||
*/ | ||
function setOwner(address owner_) external | ||
{ | ||
require(owner == address(0), "contract owner already set"); | ||
owner = owner_; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity >=0.8.0 <0.9.0; | ||
|
||
import "hardhat/console.sol"; | ||
import "remix_tests.sol"; | ||
import "remix_accounts.sol"; | ||
import "./Layer2.sol"; | ||
|
||
contract Layer2Test | ||
{ | ||
address account = TestsAccounts.getAccount(1); | ||
uint256 balance = account.balance; | ||
|
||
Layer2 l2 = new Layer2(msg.sender); | ||
Layer1 l1 = new Layer1(l2); | ||
|
||
/// #sender: account-1 | ||
/// #value: 10000000000000000000 | ||
function testExchange() public payable | ||
{ | ||
l2.setOwner(address(l1)); | ||
l1.lock{value: 5000000000000000000}(); | ||
Assert.equal(l2.balance(account), 5000000000000000000, "should have correct balance"); | ||
Assert.equal(address(l1).balance, 5000000000000000000, "should have correct balance"); | ||
|
||
l1.unlock(5000000000000000000); | ||
Assert.equal(l2.balance(account), 0, "should have correct balance"); | ||
Assert.equal(address(l1).balance, 0, "should have correct balance"); | ||
} | ||
} |