Skip to content

Commit 0639b05

Browse files
authored
feat: add BNB smart chain support (#375)
* feat: add bnb chain * Fix etherscan verify * Bump `hardhat-upgrades` * Deploy bridge on BNB chain * Add `__Pausable_init` in initialize * Fix test * fix fmt * Fix bnb address * Bump bridge version * add paybale for `logMetadata` * Add playable for `addCustomToken`
1 parent e111ba1 commit 0639b05

File tree

13 files changed

+1402
-146
lines changed

13 files changed

+1402
-146
lines changed

evm/.env.example

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
INFURA_API_KEY=
22
EVM_PRIVATE_KEY=
3-
ETHERSCAN_API_KEY=
4-
BASESCAN_API_KEY=
5-
ARBISCAN_API_KEY=
3+
ETHERSCAN_API_KEY=

evm/.openzeppelin/bsc-testnet.json

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
{
2+
"manifestVersion": "3.2",
3+
"proxies": [
4+
{
5+
"address": "0xEC81aFc3485a425347Ac03316675e58a680b283A",
6+
"txHash": "0x671b413081ad5e75c13bf2cdd63d73ce77023d8fed87ce87acce6b1d07aa79e0",
7+
"kind": "uups"
8+
}
9+
],
10+
"impls": {
11+
"2c4d3ef629440dbfa9338f12883a7fe9c537bc6b40055ff4472f0598460bbc23": {
12+
"address": "0xB9dE9F72e81d1609E940Fb2217f7286602064881",
13+
"txHash": "0x07ca6a506bcea4cca90ac15806c2ed4ff3172e5f08524aff9bfc80fe879c0503",
14+
"layout": {
15+
"solcVersion": "0.8.24",
16+
"storage": [
17+
{
18+
"label": "ethToNearToken",
19+
"offset": 0,
20+
"slot": "0",
21+
"type": "t_mapping(t_address,t_string_storage)",
22+
"contract": "OmniBridge",
23+
"src": "src/omni-bridge/contracts/OmniBridge.sol:24"
24+
},
25+
{
26+
"label": "nearToEthToken",
27+
"offset": 0,
28+
"slot": "1",
29+
"type": "t_mapping(t_string_memory_ptr,t_address)",
30+
"contract": "OmniBridge",
31+
"src": "src/omni-bridge/contracts/OmniBridge.sol:25"
32+
},
33+
{
34+
"label": "isBridgeToken",
35+
"offset": 0,
36+
"slot": "2",
37+
"type": "t_mapping(t_address,t_bool)",
38+
"contract": "OmniBridge",
39+
"src": "src/omni-bridge/contracts/OmniBridge.sol:26"
40+
},
41+
{
42+
"label": "tokenImplementationAddress",
43+
"offset": 0,
44+
"slot": "3",
45+
"type": "t_address",
46+
"contract": "OmniBridge",
47+
"src": "src/omni-bridge/contracts/OmniBridge.sol:28"
48+
},
49+
{
50+
"label": "nearBridgeDerivedAddress",
51+
"offset": 0,
52+
"slot": "4",
53+
"type": "t_address",
54+
"contract": "OmniBridge",
55+
"src": "src/omni-bridge/contracts/OmniBridge.sol:29"
56+
},
57+
{
58+
"label": "omniBridgeChainId",
59+
"offset": 20,
60+
"slot": "4",
61+
"type": "t_uint8",
62+
"contract": "OmniBridge",
63+
"src": "src/omni-bridge/contracts/OmniBridge.sol:30"
64+
},
65+
{
66+
"label": "completedTransfers",
67+
"offset": 0,
68+
"slot": "5",
69+
"type": "t_mapping(t_uint64,t_bool)",
70+
"contract": "OmniBridge",
71+
"src": "src/omni-bridge/contracts/OmniBridge.sol:32"
72+
},
73+
{
74+
"label": "currentOriginNonce",
75+
"offset": 0,
76+
"slot": "6",
77+
"type": "t_uint64",
78+
"contract": "OmniBridge",
79+
"src": "src/omni-bridge/contracts/OmniBridge.sol:33"
80+
},
81+
{
82+
"label": "customMinters",
83+
"offset": 0,
84+
"slot": "7",
85+
"type": "t_mapping(t_address,t_address)",
86+
"contract": "OmniBridge",
87+
"src": "src/omni-bridge/contracts/OmniBridge.sol:35"
88+
},
89+
{
90+
"label": "__gap",
91+
"offset": 0,
92+
"slot": "8",
93+
"type": "t_array(t_uint256)50_storage",
94+
"contract": "OmniBridge",
95+
"src": "src/omni-bridge/contracts/OmniBridge.sol:345"
96+
},
97+
{
98+
"label": "_wormhole",
99+
"offset": 0,
100+
"slot": "58",
101+
"type": "t_contract(IWormhole)6037",
102+
"contract": "OmniBridgeWormhole",
103+
"src": "src/omni-bridge/contracts/OmniBridgeWormhole.sol:27"
104+
},
105+
{
106+
"label": "_consistencyLevel",
107+
"offset": 20,
108+
"slot": "58",
109+
"type": "t_uint8",
110+
"contract": "OmniBridgeWormhole",
111+
"src": "src/omni-bridge/contracts/OmniBridgeWormhole.sol:29"
112+
},
113+
{
114+
"label": "wormholeNonce",
115+
"offset": 21,
116+
"slot": "58",
117+
"type": "t_uint32",
118+
"contract": "OmniBridgeWormhole",
119+
"src": "src/omni-bridge/contracts/OmniBridgeWormhole.sol:30"
120+
}
121+
],
122+
"types": {
123+
"t_address": {
124+
"label": "address",
125+
"numberOfBytes": "20"
126+
},
127+
"t_bool": {
128+
"label": "bool",
129+
"numberOfBytes": "1"
130+
},
131+
"t_bytes32": {
132+
"label": "bytes32",
133+
"numberOfBytes": "32"
134+
},
135+
"t_mapping(t_address,t_bool)": {
136+
"label": "mapping(address => bool)",
137+
"numberOfBytes": "32"
138+
},
139+
"t_mapping(t_bytes32,t_struct(RoleData)24_storage)": {
140+
"label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)",
141+
"numberOfBytes": "32"
142+
},
143+
"t_struct(AccessControlStorage)34_storage": {
144+
"label": "struct AccessControlUpgradeable.AccessControlStorage",
145+
"members": [
146+
{
147+
"label": "_roles",
148+
"type": "t_mapping(t_bytes32,t_struct(RoleData)24_storage)",
149+
"offset": 0,
150+
"slot": "0"
151+
}
152+
],
153+
"numberOfBytes": "32"
154+
},
155+
"t_struct(InitializableStorage)266_storage": {
156+
"label": "struct Initializable.InitializableStorage",
157+
"members": [
158+
{
159+
"label": "_initialized",
160+
"type": "t_uint64",
161+
"offset": 0,
162+
"slot": "0"
163+
},
164+
{
165+
"label": "_initializing",
166+
"type": "t_bool",
167+
"offset": 8,
168+
"slot": "0"
169+
}
170+
],
171+
"numberOfBytes": "32"
172+
},
173+
"t_struct(RoleData)24_storage": {
174+
"label": "struct AccessControlUpgradeable.RoleData",
175+
"members": [
176+
{
177+
"label": "hasRole",
178+
"type": "t_mapping(t_address,t_bool)",
179+
"offset": 0,
180+
"slot": "0"
181+
},
182+
{
183+
"label": "adminRole",
184+
"type": "t_bytes32",
185+
"offset": 0,
186+
"slot": "1"
187+
}
188+
],
189+
"numberOfBytes": "64"
190+
},
191+
"t_uint64": {
192+
"label": "uint64",
193+
"numberOfBytes": "8"
194+
},
195+
"t_array(t_uint256)50_storage": {
196+
"label": "uint256[50]",
197+
"numberOfBytes": "1600"
198+
},
199+
"t_contract(IWormhole)6037": {
200+
"label": "contract IWormhole",
201+
"numberOfBytes": "20"
202+
},
203+
"t_mapping(t_address,t_address)": {
204+
"label": "mapping(address => address)",
205+
"numberOfBytes": "32"
206+
},
207+
"t_mapping(t_address,t_string_storage)": {
208+
"label": "mapping(address => string)",
209+
"numberOfBytes": "32"
210+
},
211+
"t_mapping(t_string_memory_ptr,t_address)": {
212+
"label": "mapping(string => address)",
213+
"numberOfBytes": "32"
214+
},
215+
"t_mapping(t_uint64,t_bool)": {
216+
"label": "mapping(uint64 => bool)",
217+
"numberOfBytes": "32"
218+
},
219+
"t_string_memory_ptr": {
220+
"label": "string",
221+
"numberOfBytes": "32"
222+
},
223+
"t_string_storage": {
224+
"label": "string",
225+
"numberOfBytes": "32"
226+
},
227+
"t_uint256": {
228+
"label": "uint256",
229+
"numberOfBytes": "32"
230+
},
231+
"t_uint32": {
232+
"label": "uint32",
233+
"numberOfBytes": "4"
234+
},
235+
"t_uint8": {
236+
"label": "uint8",
237+
"numberOfBytes": "1"
238+
}
239+
},
240+
"namespaces": {
241+
"erc7201:openzeppelin.storage.AccessControl": [
242+
{
243+
"contract": "AccessControlUpgradeable",
244+
"label": "_roles",
245+
"type": "t_mapping(t_bytes32,t_struct(RoleData)24_storage)",
246+
"src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:61",
247+
"offset": 0,
248+
"slot": "0"
249+
}
250+
],
251+
"erc7201:openzeppelin.storage.Initializable": [
252+
{
253+
"contract": "Initializable",
254+
"label": "_initialized",
255+
"type": "t_uint64",
256+
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:69",
257+
"offset": 0,
258+
"slot": "0"
259+
},
260+
{
261+
"contract": "Initializable",
262+
"label": "_initializing",
263+
"type": "t_bool",
264+
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:73",
265+
"offset": 8,
266+
"slot": "0"
267+
}
268+
]
269+
}
270+
}
271+
}
272+
}
273+
}

evm/hardhat.config.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ dotenv.config()
2929
const INFURA_API_KEY = process.env.INFURA_API_KEY
3030
const EVM_PRIVATE_KEY = process.env.EVM_PRIVATE_KEY || "11".repeat(32)
3131
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY || ""
32-
const ARBISCAN_API_KEY = process.env.ARBISCAN_API_KEY || ""
33-
const BASESCAN_API_KEY = process.env.BASESCAN_API_KEY || ""
3432

3533
task("set-metadata-ft", "Set metadata for NEP-141 tokens on the Ethereum side")
3634
.addParam("nearTokenAccount", "Near account id of the token")
@@ -289,6 +287,13 @@ const config: HardhatUserConfig = {
289287
url: `https://base-mainnet.infura.io/v3/${INFURA_API_KEY}`,
290288
accounts: [`${EVM_PRIVATE_KEY}`],
291289
},
290+
bnbMainnet: {
291+
wormholeAddress: "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B",
292+
omniChainId: 5,
293+
chainId: 56,
294+
url: `https://bsc-mainnet.infura.io/v3/${INFURA_API_KEY}`,
295+
accounts: [`${EVM_PRIVATE_KEY}`],
296+
},
292297
sepolia: {
293298
omniChainId: 0,
294299
chainId: 11155111,
@@ -309,16 +314,16 @@ const config: HardhatUserConfig = {
309314
url: `https://base-sepolia.infura.io/v3/${INFURA_API_KEY}`,
310315
accounts: [`${EVM_PRIVATE_KEY}`],
311316
},
317+
bnbTestnet: {
318+
wormholeAddress: "0x68605AD7b15c732a30b1BbC62BE8F2A509D74b4D",
319+
omniChainId: 5,
320+
chainId: 97,
321+
url: `https://bsc-testnet.infura.io/v3/${INFURA_API_KEY}`,
322+
accounts: [`${EVM_PRIVATE_KEY}`],
323+
},
312324
},
313325
etherscan: {
314-
apiKey: {
315-
mainnet: ETHERSCAN_API_KEY,
316-
arbitrumOne: ARBISCAN_API_KEY,
317-
base: BASESCAN_API_KEY,
318-
sepolia: ETHERSCAN_API_KEY,
319-
arbitrumSepolia: ARBISCAN_API_KEY,
320-
baseSepolia: BASESCAN_API_KEY,
321-
},
326+
apiKey: ETHERSCAN_API_KEY,
322327
},
323328
}
324329

evm/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
"@nomicfoundation/hardhat-chai-matchers": "^2.0.8",
1515
"@nomicfoundation/hardhat-ethers": "^3.0.6",
1616
"@nomicfoundation/hardhat-network-helpers": "^1.0.12",
17-
"@nomicfoundation/hardhat-verify": "^2.0.12",
18-
"@openzeppelin/hardhat-upgrades": "^3.5.0",
17+
"@nomicfoundation/hardhat-verify": "^2.1.1",
18+
"@openzeppelin/hardhat-upgrades": "^3.9.1",
1919
"@typechain/ethers-v6": "^0.5.1",
2020
"@typechain/hardhat": "^9.1.0",
2121
"@types/chai": "4",
@@ -43,5 +43,6 @@
4343
"lint:js:fix": "biome check --write",
4444
"lint": "prettier --list-different --plugin=prettier-plugin-solidity '**/*.sol'",
4545
"lint:fix": "prettier --write --plugin=prettier-plugin-solidity '**/*.sol'"
46-
}
46+
},
47+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
4748
}

evm/src/eNear/contracts/ENearProxy.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ contract ENearProxy is UUPSUpgradeable, AccessControlUpgradeable, ICustomMinter,
2727
function initialize(address _eNear, address _prover, bytes memory _nearConnector, uint256 _currentReceiptId, address _adminAddress) public initializer {
2828
__UUPSUpgradeable_init();
2929
__AccessControl_init();
30+
__Pausable_init();
3031
eNear = IENear(_eNear);
3132
nearConnector = _nearConnector;
3233
currentReceiptId = _currentReceiptId;

evm/src/omni-bridge/contracts/OmniBridge.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ contract OmniBridge is
6666
_grantRole(PAUSABLE_ADMIN_ROLE, _msgSender());
6767
}
6868

69-
function addCustomToken(string calldata nearTokenId, address tokenAddress, address customMinter, uint8 originDecimals) external onlyRole(DEFAULT_ADMIN_ROLE) {
69+
function addCustomToken(string calldata nearTokenId, address tokenAddress, address customMinter, uint8 originDecimals) payable external onlyRole(DEFAULT_ADMIN_ROLE) {
7070
isBridgeToken[tokenAddress] = true;
7171
ethToNearToken[tokenAddress] = nearTokenId;
7272
nearToEthToken[nearTokenId] = tokenAddress;
@@ -171,7 +171,7 @@ contract OmniBridge is
171171

172172
function logMetadata(
173173
address tokenAddress
174-
) external {
174+
) payable external {
175175
string memory name = IERC20Metadata(tokenAddress).name();
176176
string memory symbol = IERC20Metadata(tokenAddress).symbol();
177177
uint8 decimals = IERC20Metadata(tokenAddress).decimals();

0 commit comments

Comments
 (0)