Skip to content

Commit

Permalink
add whitelist for messager caller
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoch05 committed Sep 20, 2023
1 parent 5ddf2c8 commit 05362b7
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 53 deletions.
13 changes: 12 additions & 1 deletion helix-contract/contracts/ln/base/LnAccessController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ contract LnAccessController is Pausable {
address public dao;
address public operator;

mapping(address=>bool) public callerWhiteList;

modifier onlyDao() {
require(msg.sender == dao, "!dao");
_;
Expand All @@ -20,15 +22,24 @@ contract LnAccessController is Pausable {
_;
}

modifier onlyWhiteListCaller() {
require(callerWhiteList[msg.sender], "caller not in white list");
_;
}

function _initialize(address _dao) internal {
dao = _dao;
operator = msg.sender;
operator = _dao;
}

function setOperator(address _operator) onlyDao external {
operator = _operator;
}

function authoriseAppCaller(address appAddress, bool enable) onlyOperator external {
callerWhiteList[appAddress] = enable;
}

function transferOwnership(address _dao) onlyDao external {
dao = _dao;
}
Expand Down
6 changes: 3 additions & 3 deletions helix-contract/contracts/ln/messager/AxelarMessager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,21 @@ contract AxelarMessager is LnAccessController {
trustedRemotes[_remoteChainName] = _remoteMessager;
}

function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
RemoteMessager memory remoteMessager = remoteMessagers[_remoteChainId];
require(remoteMessager.messager != address(0), "remote not configured");
bytes32 key = keccak256(abi.encodePacked(remoteMessager.axRemoteChainName, msg.sender));
remoteAppReceivers[key] = _remoteBridge;
}

function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
RemoteMessager memory remoteMessager = remoteMessagers[_remoteChainId];
require(remoteMessager.messager != address(0), "remote not configured");
bytes32 key = keccak256(abi.encodePacked(remoteMessager.axRemoteChainName, msg.sender));
remoteAppSenders[key] = _remoteBridge;
}

function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory _params) external payable {
function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory _params) onlyWhiteListCaller external payable {
address refunder = address(bytes20(_params));
RemoteMessager memory remoteMessager = remoteMessagers[_remoteChainId];
require(remoteMessager.messager != address(0), "remote not configured");
Expand Down
12 changes: 6 additions & 6 deletions helix-contract/contracts/ln/messager/Eth2ArbReceiveService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
pragma solidity ^0.8.10;

import "@arbitrum/nitro-contracts/src/libraries/AddressAliasHelper.sol";
import "../base/LnAccessController.sol";
import "../interface/ILowLevelMessager.sol";

// from ethereum to arbitrum messager
contract Eth2ArbReceiveService is ILowLevelMessageReceiver {
contract Eth2ArbReceiveService is ILowLevelMessageReceiver, LnAccessController {
uint256 immutable public REMOTE_CHAINID;
address public remoteMessagerAlias;

Expand All @@ -16,17 +17,16 @@ contract Eth2ArbReceiveService is ILowLevelMessageReceiver {
_;
}

constructor(uint256 _remoteChainId) {
constructor(address _dao, uint256 _remoteChainId) {
_initialize(_dao);
REMOTE_CHAINID = _remoteChainId;
}

// only can be set once
function setRemoteMessager(address _remoteMessager) external {
require(remoteMessagerAlias == address(0), "remote exist");
function setRemoteMessager(address _remoteMessager) onlyOperator external {
remoteMessagerAlias = AddressAliasHelper.applyL1ToL2Alias(_remoteMessager);
}

function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
appPairs[msg.sender] = _remoteBridge;
}
Expand Down
14 changes: 7 additions & 7 deletions helix-contract/contracts/ln/messager/Eth2ArbSendService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@
pragma solidity ^0.8.10;

import "@arbitrum/nitro-contracts/src/bridge/IInbox.sol";
import "../base/LnAccessController.sol";
import "../interface/ILowLevelMessager.sol";

// from ethereum to arbitrum messager
contract Eth2ArbSendService is ILowLevelMessageSender {
contract Eth2ArbSendService is ILowLevelMessageSender, LnAccessController {
uint256 immutable public REMOTE_CHAINID;
IInbox public inbox;
address public remoteMessager;
mapping(address=>address) public appPairs;

constructor(address _inbox, uint256 _remoteChainId) {
constructor(address _dao, address _inbox, uint256 _remoteChainId) {
_initialize(_dao);
inbox = IInbox(_inbox);
REMOTE_CHAINID = _remoteChainId;
}

// only can be set once
function setRemoteMessager(address _remoteMessager) external {
require(remoteMessager == address(0), "remote exist");
function setRemoteMessager(address _remoteMessager) onlyOperator external {
remoteMessager = _remoteMessager;
}

function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
appPairs[msg.sender] = _remoteBridge;
}

function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory _params) external payable {
function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory _params) onlyWhiteListCaller external payable {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
address remoteAppAddress = appPairs[msg.sender];
require(remoteAppAddress != address(0), "app not registered");
Expand Down
12 changes: 6 additions & 6 deletions helix-contract/contracts/ln/messager/Eth2LineaReceiveService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
pragma solidity ^0.8.10;

import "./interface/ILineaMessageService.sol";
import "../base/LnAccessController.sol";
import "../interface/ILowLevelMessager.sol";

// from ethereum to linea messager
contract Eth2LineaReceiveService is ILowLevelMessageReceiver {
contract Eth2LineaReceiveService is ILowLevelMessageReceiver, LnAccessController {
uint256 immutable public REMOTE_CHAINID;
ILineaMessageService public messageService;
address public remoteMessager;
Expand All @@ -18,18 +19,17 @@ contract Eth2LineaReceiveService is ILowLevelMessageReceiver {
_;
}

constructor(address _messageService, uint256 _remoteChainId) {
constructor(address _dao, address _messageService, uint256 _remoteChainId) {
_initialize(_dao);
messageService = ILineaMessageService(_messageService);
REMOTE_CHAINID = _remoteChainId;
}

// only can be set once
function setRemoteMessager(address _remoteMessager) external {
require(remoteMessager == address(0), "remote exist");
function setRemoteMessager(address _remoteMessager) onlyOperator external {
remoteMessager = _remoteMessager;
}

function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
appPairs[msg.sender] = _remoteBridge;
}
Expand Down
15 changes: 7 additions & 8 deletions helix-contract/contracts/ln/messager/Eth2LineaSendService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,33 @@
pragma solidity ^0.8.10;

import "./interface/ILineaMessageService.sol";
import "../base/LnAccessController.sol";
import "../interface/ILowLevelMessager.sol";

// from ethereum to linea messager
contract Eth2LineaSendService is ILowLevelMessageSender {
contract Eth2LineaSendService is ILowLevelMessageSender, LnAccessController {
uint256 immutable public REMOTE_CHAINID;
ILineaMessageService public messageService;
address public remoteMessager;

mapping(address=>address) public appPairs;

constructor(address _messageService, uint256 _remoteChainId) {
constructor(address _dao, address _messageService, uint256 _remoteChainId) {
_initialize(_dao);
messageService = ILineaMessageService(_messageService);
REMOTE_CHAINID = _remoteChainId;
}

// only can be set once
function setRemoteMessager(address _remoteMessager) external {
require(remoteMessager == address(0), "remote exist");
function setRemoteMessager(address _remoteMessager) onlyOperator external {
remoteMessager = _remoteMessager;
}

function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
appPairs[msg.sender] = _remoteBridge;
}

function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory) external payable {
function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory) onlyWhiteListCaller external payable {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
address remoteAppAddress = appPairs[msg.sender];
require(remoteAppAddress != address(0), "app not registered");
Expand All @@ -46,4 +46,3 @@ contract Eth2LineaSendService is ILowLevelMessageSender {
);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
pragma solidity ^0.8.10;

import "./interface/IZksyncMailbox.sol";
import "../base/LnAccessController.sol";
import "../interface/ILowLevelMessager.sol";

// from ethereum to zkSync messager
contract Eth2ZkSyncReceiveService is ILowLevelMessageReceiver {
contract Eth2ZkSyncReceiveService is ILowLevelMessageReceiver, LnAccessController {
uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);
uint256 immutable public REMOTE_CHAINID;
IMailbox public mailbox;
Expand All @@ -18,17 +19,17 @@ contract Eth2ZkSyncReceiveService is ILowLevelMessageReceiver {
_;
}

constructor(address _mailbox, uint256 _remoteChainId) {
constructor(address _dao, address _mailbox, uint256 _remoteChainId) {
_initialize(_dao);
mailbox = IMailbox(_mailbox);
REMOTE_CHAINID = _remoteChainId;
}

// only can be set once
function setRemoteMessager(address _remoteMessager) external {
function setRemoteMessager(address _remoteMessager) onlyOperator external {
remoteMessagerAlias = address(uint160(_remoteMessager) + offset);
}

function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
appPairs[msg.sender] = _remoteBridge;
}
Expand Down
14 changes: 7 additions & 7 deletions helix-contract/contracts/ln/messager/Eth2ZkSyncSendService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,33 @@
pragma solidity ^0.8.10;

import "./interface/IZksyncMailbox.sol";
import "../base/LnAccessController.sol";
import "../interface/ILowLevelMessager.sol";

// from ethereum to zkSync messager
contract Eth2ZkSyncSendService is ILowLevelMessageSender {
contract Eth2ZkSyncSendService is ILowLevelMessageSender, LnAccessController {
uint256 immutable public REMOTE_CHAINID;
IMailbox public mailbox;
address public remoteMessager;

mapping(address=>address) public appPairs;

constructor(address _mailbox, uint256 _remoteChainId) {
constructor(address _dao, address _mailbox, uint256 _remoteChainId) {
_initialize(_dao);
mailbox = IMailbox(_mailbox);
REMOTE_CHAINID = _remoteChainId;
}

// only can be set once
function setRemoteMessager(address _remoteMessager) external {
require(remoteMessager == address(0), "remote exist");
function setRemoteMessager(address _remoteMessager) onlyOperator external {
remoteMessager = _remoteMessager;
}

function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
appPairs[msg.sender] = _remoteBridge;
}

function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory _params) external payable {
function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory _params) onlyWhiteListCaller external payable {
require(_remoteChainId == REMOTE_CHAINID, "invalid remote chainId");
address remoteAppAddress = appPairs[msg.sender];
require(remoteAppAddress != address(0), "app not registered");
Expand Down
12 changes: 8 additions & 4 deletions helix-contract/contracts/ln/messager/LayerZeroMessager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ contract LayerZeroMessager is LnAccessController {
mapping(bytes32=>address) public remoteAppSenders;

event CallResult(uint16 lzRemoteChainId, bytes srcAddress, bool successed);
event CallerUnMatched(uint16 lzRemoteChainId, bytes srcAddress, address remoteAppAddress);

constructor(address _dao, address _endpoint) {
_initialize(_dao);
Expand All @@ -41,21 +42,21 @@ contract LayerZeroMessager is LnAccessController {
trustedRemotes[_lzRemoteChainId] = keccak256(abi.encodePacked(_remoteMessager, address(this)));
}

function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteReceiver(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
RemoteMessager memory remoteMessager = remoteMessagers[_remoteChainId];
require(remoteMessager.messager != address(0), "remote not configured");
bytes32 key = keccak256(abi.encodePacked(remoteMessager.lzRemoteChainId, msg.sender));
remoteAppReceivers[key] = _remoteBridge;
}

function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) external {
function registerRemoteSender(uint256 _remoteChainId, address _remoteBridge) onlyWhiteListCaller external {
RemoteMessager memory remoteMessager = remoteMessagers[_remoteChainId];
require(remoteMessager.messager != address(0), "remote not configured");
bytes32 key = keccak256(abi.encodePacked(remoteMessager.lzRemoteChainId, msg.sender));
remoteAppSenders[key] = _remoteBridge;
}

function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory _params) external payable {
function sendMessage(uint256 _remoteChainId, bytes memory _message, bytes memory _params) onlyWhiteListCaller external payable {
address refunder = address(bytes20(_params));
RemoteMessager memory remoteMessager = remoteMessagers[_remoteChainId];
require(remoteMessager.messager != address(0), "remote not configured");
Expand Down Expand Up @@ -86,7 +87,10 @@ contract LayerZeroMessager is LnAccessController {
// call
(address remoteAppAddress, address localAppAddress, bytes memory message) = abi.decode(_payload, (address, address, bytes));
bytes32 key = keccak256(abi.encodePacked(_srcChainId, localAppAddress));
require(remoteAppAddress == remoteAppSenders[key], "invalid remote address");
if (remoteAppAddress != remoteAppSenders[key]) {
emit CallerUnMatched(_srcChainId, _srcAddress, remoteAppAddress);
return;
}
(bool success,) = localAppAddress.call(message);
// don't revert to prevent message block
emit CallResult(_srcChainId, _srcAddress, success);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.10;
import "../messager/Eth2ArbReceiveService.sol";

contract MockEth2ArbReceiveService is Eth2ArbReceiveService {
constructor(uint256 _remoteChainId) Eth2ArbReceiveService(_remoteChainId) {}
constructor(address _dao, uint256 _remoteChainId) Eth2ArbReceiveService(_dao, _remoteChainId) {}

function setRemoteMessagerAlias(address _remoteMessagerAlias) external {
remoteMessagerAlias = _remoteMessagerAlias;
Expand Down
10 changes: 8 additions & 2 deletions helix-contract/test/3_test_ln_opposite.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ describe("eth->arb lnv2 positive bridge tests", () => {
// eth -> arb messager service
console.log("deploy etherum to arbitrum l1->l2 message service");
const eth2arbSendServiceContract = await ethers.getContractFactory("Eth2ArbSendService");
const eth2arbSendService = await eth2arbSendServiceContract.deploy(inbox.address, arbChainId);
const eth2arbSendService = await eth2arbSendServiceContract.deploy(dao, inbox.address, arbChainId);
await eth2arbSendService.deployed();
const eth2arbRecvServiceContract = await ethers.getContractFactory("MockEth2ArbReceiveService");
const eth2arbRecvService = await eth2arbRecvServiceContract.deploy(ethChainId);
const eth2arbRecvService = await eth2arbRecvServiceContract.deploy(dao, ethChainId);
await eth2arbRecvService.deployed();

await eth2arbSendService.setRemoteMessager(eth2arbRecvService.address);
Expand All @@ -151,6 +151,12 @@ describe("eth->arb lnv2 positive bridge tests", () => {
console.log("messager service deploy finished");

console.log("configure message service for token bridge");
// authorise
await eth2arbSendService.authoriseAppCaller(ethBridge.address, true);
await eth2arbRecvService.authoriseAppCaller(arbBridge.address, true);
await lzMessagerEth.authoriseAppCaller(ethBridge.address, true);
await lzMessagerArb.authoriseAppCaller(arbBridge.address, true);

await ethBridge.setSendService(arbChainId, arbBridge.address, eth2arbSendService.address);
await ethBridge.setReceiveService(arbChainId, arbBridge.address, lzMessagerEth.address);
await arbBridge.setSendService(ethChainId, ethBridge.address, lzMessagerArb.address);
Expand Down
8 changes: 5 additions & 3 deletions helix-contract/test/4_test_ln_layerzero.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ describe("eth->arb lnv2 layerzero bridge tests", () => {
// ******************* register token **************

// set bridge infos
lnDefaultBridgeEth.setSendService(arbChainId, lnDefaultBridgeArb.address, lzMessagerEth.address);
lnDefaultBridgeArb.setReceiveService(ethChainId, lnDefaultBridgeEth.address, lzMessagerArb.address);
await lzMessagerEth.authoriseAppCaller(lnDefaultBridgeEth.address, true);
await lzMessagerArb.authoriseAppCaller(lnDefaultBridgeArb.address, true);
await lnDefaultBridgeEth.setSendService(arbChainId, lnDefaultBridgeArb.address, lzMessagerEth.address);
await lnDefaultBridgeArb.setReceiveService(ethChainId, lnDefaultBridgeEth.address, lzMessagerArb.address);
console.log("deploy bridge finished");

// provider
Expand Down Expand Up @@ -303,7 +305,7 @@ describe("eth->arb lnv2 layerzero bridge tests", () => {
));
expect(fillInfo.timestamp).to.equal(relayTimestamp);
expect(balanceOfUserAfter - balanceOfUser).to.equal(transferAmount);
expect(balanceOfSlasherAfter - balanceOfSlasher).to.equal(penalty + totalFee);
expect(balanceOfSlasherAfter - balanceOfSlasher).to.equal(penalty + totalFee - protocolFee);
}
expect(fillInfo.slasher).to.equal(slasher.address);
return slashTransaction;
Expand Down

0 comments on commit 05362b7

Please sign in to comment.