Skip to content

Commit 7333cc0

Browse files
committed
feat: SignetL1
1 parent c8c5f5d commit 7333cc0

File tree

6 files changed

+182
-4
lines changed

6 files changed

+182
-4
lines changed

foundry.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ libs = ["lib"]
55

66
via-ir = true
77

8-
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
9-
10-
118
[lint]
9+
ignore = ["src/vendor/*"]
1210
exclude_lints = ["unwrapped-modifier-logic"]

src/apps/Morpho.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,11 @@ contract HosyMorphoBorrow is HostMorphoUser {
249249
// borrow some amount of loanToken
250250
MORPHO.borrow(loadParams(), amount, 0, onBehalf, address(this));
251251

252+
// TODO: complete implementation
252253
// User logic to use the tokens goes here.
253254
// Could send the tokens to the rollup via Passage, or do something
254255
// else :)
256+
filler;
255257

256258
return true;
257259
}

src/chains/Pecorino.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ pragma solidity ^0.8.13;
33

44
import {RollupOrders} from "zenith/src/orders/RollupOrders.sol";
55
import {RollupPassage} from "zenith/src/passage/RollupPassage.sol";
6+
import {HostOrders} from "zenith/src/orders/HostOrders.sol";
7+
import {Passage} from "zenith/src/passage/Passage.sol";
68
import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
79

810
/// @title PecorinoConstants
@@ -16,6 +18,12 @@ library PecorinoConstants {
1618
/// @notice The Pecorino Rollup chain ID.
1719
uint32 constant ROLLUP_CHAIN_ID = 14174;
1820

21+
/// @notice The Passage contract for the Pecorino testnet host chain.
22+
Passage constant HOST_PASSAGE = Passage(payable(0x12585352AA1057443D6163B539EfD4487f023182));
23+
24+
/// @notice The HostOrders contract for the Pecorino testnet host chain.
25+
HostOrders constant HOST_ORDERS = HostOrders(0x0A4f505364De0Aa46c66b15aBae44eBa12ab0380);
26+
1927
/// @notice The Rollup Passage contract for the Pecorino testnet.
2028
RollupPassage constant PECORINO_ROLLUP_PASSAGE = RollupPassage(payable(0x0000000000007369676E65742D70617373616765));
2129

src/l1/Signet.sol

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {HostOrders} from "zenith/src/orders/HostOrders.sol";
5+
import {Passage} from "zenith/src/passage/Passage.sol";
6+
import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
7+
8+
import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol";
9+
import {PecorinoConstants} from "../chains/Pecorino.sol";
10+
11+
abstract contract SignetL1 {
12+
/// @notice Sentinal value for the native asset in order inputs/outputs
13+
address constant NATIVE_ASSET = address(0);
14+
15+
/// @notice The Passage address
16+
Passage internal immutable PASSAGE;
17+
/// @notice The Host Orders address
18+
HostOrders internal immutable ORDERS;
19+
20+
/// @notice The WETH token address.
21+
IERC20 internal immutable WETH;
22+
/// @notice The WBTC token address.
23+
IERC20 internal immutable WBTC;
24+
/// @notice The USDC token address.
25+
IERC20 internal immutable USDC;
26+
/// @notice The USDT token address.
27+
IERC20 internal immutable USDT;
28+
29+
/// @notice The Rollup WUSD token address.
30+
address internal immutable RU_WUSD;
31+
/// @notice The Rollup WBTC token address.
32+
address internal immutable RU_WBTC;
33+
/// @notice The Rollup WETH token address.
34+
address internal immutable RU_WETH;
35+
36+
/// @notice Error for unsupported chain IDs.
37+
error UnsupportedChain(uint256);
38+
39+
constructor() {
40+
if (block.chainid == PecorinoConstants.HOST_CHAIN_ID) {
41+
PASSAGE = PecorinoConstants.HOST_PASSAGE;
42+
ORDERS = PecorinoConstants.HOST_ORDERS;
43+
44+
WETH = IERC20(PecorinoConstants.HOST_WETH);
45+
WBTC = IERC20(PecorinoConstants.HOST_WBTC);
46+
USDC = IERC20(PecorinoConstants.HOST_USDC);
47+
USDT = IERC20(PecorinoConstants.HOST_USDT);
48+
49+
RU_WUSD = address(PecorinoConstants.WUSD);
50+
RU_WBTC = address(PecorinoConstants.WBTC);
51+
RU_WETH = address(PecorinoConstants.WETH);
52+
} else {
53+
revert UnsupportedChain(block.chainid);
54+
}
55+
}
56+
57+
/// @notice This is used to know whether to alias. It should generally
58+
/// return false. If writing an ephemeral contract, override to return true.
59+
function isEphemeral() internal pure virtual returns (bool) {
60+
return false;
61+
}
62+
63+
/// @notice Returns
64+
function selfOnL2() internal view returns (address) {
65+
if (isEphemeral()) {
66+
return address(this);
67+
}
68+
if (address(this).code.length == 23) {
69+
bool is7702;
70+
assembly {
71+
let ptr := mload(0x40)
72+
extcodecopy(caller(), ptr, 0, 0x20)
73+
is7702 := eq(shr(232, mload(ptr)), 0xEF0100)
74+
// clean the memory we used. Unnecessary, but good hygiene
75+
mstore(ptr, 0x0)
76+
}
77+
if (is7702) {
78+
return address(this);
79+
}
80+
}
81+
return AddressAliasHelper.applyL1ToL2Alias(address(this));
82+
}
83+
84+
function makeOutput(address token, uint256 amount, address recipient)
85+
internal
86+
pure
87+
returns (HostOrders.Output memory output)
88+
{
89+
output.token = token;
90+
output.amount = amount;
91+
output.recipient = recipient;
92+
output.chainId = PecorinoConstants.HOST_CHAIN_ID;
93+
}
94+
95+
function usdcOutput(uint256 amount, address recipient) internal view returns (HostOrders.Output memory output) {
96+
return makeOutput(address(USDC), amount, recipient);
97+
}
98+
99+
function usdtOutput(uint256 amount, address recipient) internal view returns (HostOrders.Output memory output) {
100+
return makeOutput(address(USDT), amount, recipient);
101+
}
102+
103+
function wbtcOutput(uint256 amount, address recipient) internal view returns (HostOrders.Output memory output) {
104+
return makeOutput(address(WBTC), amount, recipient);
105+
}
106+
107+
function wethOutput(uint256 amount, address recipient) internal view returns (HostOrders.Output memory output) {
108+
return makeOutput(address(WETH), amount, recipient);
109+
}
110+
111+
function ethOutput(uint256 amount, address recipient) internal pure returns (HostOrders.Output memory output) {
112+
return makeOutput(NATIVE_ASSET, amount, recipient);
113+
}
114+
115+
function enterSignetToken(address token, uint256 amount) internal {
116+
if (token == NATIVE_ASSET) {
117+
enterSignetEth(amount);
118+
return;
119+
}
120+
IERC20(token).approve(address(PASSAGE), amount);
121+
PASSAGE.enterToken(selfOnL2(), token, amount);
122+
}
123+
124+
function enterSignetEth(uint256 amount) internal {
125+
PASSAGE.enter{value: amount}(selfOnL2());
126+
}
127+
}

src/l2/Signet.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ contract SignetL2 {
5555
HOST_WBTC = PecorinoConstants.HOST_WBTC;
5656
HOST_WETH = PecorinoConstants.HOST_WETH;
5757
} else {
58-
revert("Unsupported chain");
58+
revert UnsupportedChain(block.chainid);
5959
}
6060
}
6161

src/vendor/AddressAliasHelper.sol

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
/*
4+
* Copyright 2019-2021, Offchain Labs, Inc.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
pragma solidity ^0.8.0;
20+
21+
library AddressAliasHelper {
22+
uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);
23+
24+
/// @notice Utility function that converts the address in the L1 that submitted a tx to
25+
/// the inbox to the msg.sender viewed in the L2
26+
/// @param l1Address the address in the L1 that triggered the tx to L2
27+
/// @return l2Address L2 address as viewed in msg.sender
28+
function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {
29+
unchecked {
30+
l2Address = address(uint160(l1Address) + offset);
31+
}
32+
}
33+
34+
/// @notice Utility function that converts the msg.sender viewed in the L2 to the
35+
/// address in the L1 that submitted a tx to the inbox
36+
/// @param l2Address L2 address as viewed in msg.sender
37+
/// @return l1Address the address in the L1 that triggered the tx to L2
38+
function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {
39+
unchecked {
40+
l1Address = address(uint160(l2Address) - offset);
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)