Skip to content

Commit 5097e92

Browse files
Experimental new version w/ comms
0 parents  commit 5097e92

15 files changed

+9747
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Packages
2+
node_modules/
3+
4+
# Hardhat build outputs
5+
artifacts/
6+
cache/

README.md

Whitespace-only changes.

contracts/ERC20.sol

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >0.6.0 <0.8.0;
3+
4+
/**
5+
* @title ERC20
6+
* @dev A super simple ERC20 implementation!
7+
*/
8+
contract ERC20 {
9+
10+
/**********
11+
* Events *
12+
**********/
13+
14+
event Transfer(
15+
address indexed _from,
16+
address indexed _to,
17+
uint256 _value
18+
);
19+
20+
event Approval(
21+
address indexed _owner,
22+
address indexed _spender,
23+
uint256 _value
24+
);
25+
26+
27+
/*************
28+
* Variables *
29+
*************/
30+
31+
mapping (address => uint256) public balances;
32+
mapping (address => mapping (address => uint256)) public allowances;
33+
34+
// Some optional extra goodies.
35+
uint256 public totalSupply;
36+
string public name;
37+
38+
39+
/***************
40+
* Constructor *
41+
***************/
42+
43+
/**
44+
* @param _initialSupply Initial maximum token supply.
45+
* @param _name A name for our ERC20 (technically optional, but it's fun ok jeez).
46+
*/
47+
constructor(
48+
uint256 _initialSupply,
49+
string memory _name
50+
)
51+
public
52+
{
53+
balances[msg.sender] = _initialSupply;
54+
totalSupply = _initialSupply;
55+
name = _name;
56+
}
57+
58+
59+
/********************
60+
* Public Functions *
61+
********************/
62+
63+
/**
64+
* Checks the balance of an address.
65+
* @param _owner Address to check a balance for.
66+
* @return Balance of the address.
67+
*/
68+
function balanceOf(
69+
address _owner
70+
)
71+
external
72+
view
73+
returns (
74+
uint256
75+
)
76+
{
77+
return balances[_owner];
78+
}
79+
80+
/**
81+
* Transfers a balance from your account to someone else's account!
82+
* @param _to Address to transfer a balance to.
83+
* @param _amount Amount to transfer to the other account.
84+
* @return true if the transfer was successful.
85+
*/
86+
function transfer(
87+
address _to,
88+
uint256 _amount
89+
)
90+
external
91+
returns (
92+
bool
93+
)
94+
{
95+
require(
96+
balances[msg.sender] >= _amount,
97+
"You don't have enough balance to make this transfer!"
98+
);
99+
100+
balances[msg.sender] -= _amount;
101+
balances[_to] += _amount;
102+
103+
emit Transfer(
104+
msg.sender,
105+
_to,
106+
_amount
107+
);
108+
109+
return true;
110+
}
111+
112+
/**
113+
* Transfers a balance from someone else's account to another account. You need an allowance
114+
* from the sending account for this to work!
115+
* @param _from Account to transfer a balance from.
116+
* @param _to Account to transfer a balance to.
117+
* @param _amount Amount to transfer to the other account.
118+
* @return true if the transfer was successful.
119+
*/
120+
function transferFrom(
121+
address _from,
122+
address _to,
123+
uint256 _amount
124+
)
125+
external
126+
returns (
127+
bool
128+
)
129+
{
130+
require(
131+
balances[_from] >= _amount,
132+
"Can't transfer from the desired account because it doesn't have enough balance."
133+
);
134+
135+
require(
136+
allowances[_from][msg.sender] >= _amount,
137+
"Can't transfer from the desired account because you don't have enough of an allowance."
138+
);
139+
140+
balances[_to] += _amount;
141+
balances[_from] -= _amount;
142+
143+
emit Transfer(
144+
_from,
145+
_to,
146+
_amount
147+
);
148+
149+
return true;
150+
}
151+
152+
/**
153+
* Approves an account to spend some amount from your account.
154+
* @param _spender Account to approve a balance for.
155+
* @param _amount Amount to allow the account to spend from your account.
156+
* @return true if the allowance was successful.
157+
*/
158+
function approve(
159+
address _spender,
160+
uint256 _amount
161+
)
162+
external
163+
returns (
164+
bool
165+
)
166+
{
167+
allowances[msg.sender][_spender] = _amount;
168+
169+
emit Approval(
170+
msg.sender,
171+
_spender,
172+
_amount
173+
);
174+
175+
return true;
176+
}
177+
178+
/**
179+
* Checks how much a given account is allowed to spend from another given account.
180+
* @param _owner Address of the account to check an allowance from.
181+
* @param _spender Address of the account trying to spend from the owner.
182+
* @return Allowance for the spender from the owner.
183+
*/
184+
function allowance(
185+
address _owner,
186+
address _spender
187+
)
188+
external
189+
view
190+
returns (
191+
uint256
192+
)
193+
{
194+
return allowances[_owner][_spender];
195+
}
196+
}

contracts/ERC20Adapter.sol

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >0.6.0 <0.8.0;
3+
4+
import { ERC20 } from "./ERC20.sol";
5+
import { Layer2Bridged } from "./Layer2Bridged.sol";
6+
7+
contract ERC20Adapter is Layer2Bridged {
8+
ERC20 erc20;
9+
10+
constructor(
11+
ERC20 _erc20
12+
)
13+
public
14+
{
15+
erc20 = _erc20;
16+
}
17+
18+
function deposit(
19+
address _depositor,
20+
uint256 _amount
21+
)
22+
public
23+
{
24+
// 1. Transfer the amount from the depositor to this contract.
25+
erc20.transferFrom(
26+
_depositor,
27+
address(this),
28+
_amount
29+
);
30+
31+
// 2. Generate a contract call to be executed on Layer 2.
32+
bytes memory message = abi.encodeWithSignature(
33+
"mint(address,uint256)",
34+
_depositor,
35+
_amount
36+
);
37+
38+
// 3. Send the message to our partner contract.
39+
sendMessageViaBridge(
40+
message,
41+
8000000
42+
);
43+
}
44+
45+
function withdraw(
46+
address _withdrawer,
47+
uint256 _amount
48+
)
49+
public
50+
onlyViaBridge
51+
{
52+
erc20.transfer(
53+
_withdrawer,
54+
_amount
55+
);
56+
}
57+
}

contracts/Layer2Bridged.sol

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >0.6.0 <0.8.0;
3+
4+
import { iOVM_BaseCrossDomainMessenger } from "@eth-optimism/contracts/build/contracts/iOVM/bridge/iOVM_BaseCrossDomainMessenger.sol";
5+
6+
contract Layer2Bridged {
7+
address internal owner;
8+
address internal partner;
9+
address internal bridge;
10+
11+
constructor()
12+
public
13+
{
14+
owner = msg.sender;
15+
}
16+
17+
modifier onlyOwner() {
18+
require(
19+
msg.sender == owner,
20+
"Layer2Bridged: Function can only be called by the contract owner."
21+
);
22+
_;
23+
}
24+
25+
modifier onlyViaBridge() {
26+
require(
27+
msg.sender == bridge,
28+
"Layer2Bridged: Function can only be called by the bridge contract."
29+
);
30+
31+
require(
32+
iOVM_BaseCrossDomainMessenger(
33+
bridge
34+
).xDomainMessageSender() == partner,
35+
"Layer2Bridged: Function can only be triggered by the partner contract."
36+
);
37+
38+
_;
39+
}
40+
41+
function createBridge(
42+
address _partner,
43+
address _bridge
44+
)
45+
public
46+
onlyOwner
47+
{
48+
partner = _partner;
49+
bridge = _bridge;
50+
}
51+
52+
function sendMessageViaBridge(
53+
bytes memory _message,
54+
uint32 _gasLimit
55+
)
56+
internal
57+
{
58+
iOVM_BaseCrossDomainMessenger(
59+
bridge
60+
).sendMessage(
61+
partner,
62+
_message,
63+
_gasLimit
64+
);
65+
}
66+
}

contracts/Layer2ERC20.sol

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >0.6.0 <0.8.0;
3+
4+
import { ERC20 } from "./ERC20.sol";
5+
import { Layer2Bridged } from "./Layer2Bridged.sol";
6+
7+
contract Layer2ERC20 is ERC20, Layer2Bridged {
8+
9+
/**
10+
* @param _initialSupply Initial maximum token supply.
11+
* @param _name A name for our ERC20 (technically optional, but it's fun ok jeez).
12+
*/
13+
constructor(
14+
uint256 _initialSupply,
15+
string memory _name
16+
)
17+
public
18+
ERC20(_initialSupply, _name)
19+
{}
20+
21+
function mint(
22+
address _recipient,
23+
uint256 _amount
24+
)
25+
public
26+
onlyViaBridge
27+
{
28+
balances[_recipient] += _amount;
29+
totalSupply += _amount;
30+
}
31+
32+
function withdraw(
33+
uint256 _amount
34+
)
35+
public
36+
{
37+
require(
38+
balances[msg.sender] >= _amount,
39+
"You don't have enough balance!"
40+
);
41+
42+
balances[msg.sender] -= _amount;
43+
totalSupply -= _amount;
44+
45+
bytes memory message = abi.encodeWithSignature(
46+
"withdraw(address,uint256)",
47+
msg.sender,
48+
_amount
49+
);
50+
51+
sendMessageViaBridge(
52+
message,
53+
8000000
54+
);
55+
}
56+
}

hardhat.config.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { HardhatUserConfig } from 'hardhat/types'
2+
3+
import '@nomiclabs/hardhat-ethers'
4+
import '@nomiclabs/hardhat-waffle'
5+
6+
import '@eth-optimism/plugins/hardhat/compiler'
7+
import '@eth-optimism/plugins/hardhat/ethers'
8+
9+
const config: HardhatUserConfig = {
10+
solidity: "0.7.3",
11+
};
12+
13+
export default config

0 commit comments

Comments
 (0)