Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Central Bridge Router #311

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bridge/contracts/BToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.16;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "contracts/interfaces/IBridgeRouter.sol";
import "contracts/interfaces/ICentralBridgeRouter.sol";
import "contracts/utils/Admin.sol";
import "contracts/utils/Mutex.sol";
import "contracts/utils/MagicEthTransfer.sol";
Expand Down Expand Up @@ -158,7 +158,7 @@ contract BToken is
/// @param data_ Encoded data necessary to deposit the arbitrary tokens in the bridges.
function depositTokensOnBridges(uint8 routerVersion_, bytes calldata data_) public payable {
//forward call to router
uint256 bTokenFee = IBridgeRouter(_centralBridgeRouter).routeDeposit(
uint256 bTokenFee = ICentralBridgeRouter(_centralBridgeRouter).forwardDeposit(
msg.sender,
routerVersion_,
data_
Expand Down
178 changes: 178 additions & 0 deletions bridge/contracts/CentralBridgeRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.16;

import "contracts/utils/ImmutableAuth.sol";
import "contracts/interfaces/IBridgePoolRouter.sol";
import "contracts/interfaces/ICentralBridgeRouter.sol";
import "contracts/libraries/errors/CentralBridgeRouterErrors.sol";

contract CentralBridgeRouter is ICentralBridgeRouter, ImmutableFactory, ImmutableBToken {
struct EventData {
bytes32[] topics;
bytes logData;
}

struct DepositReturnData {
EventData[] eventData;
uint256 fee;
}

struct RouterConfig {
address routerAddress;
bool notOnline;
}

// mapping of router version to data
mapping(uint16 => RouterConfig) internal _routerConfig;
uint256 internal _nonce;

//tracker to track number of deployed router versions
uint16 internal _routerVersions;

// event DepositedERCToken(
// address ercContract,
// uint8 destinationAccountType, // 1 for secp256k1, 2 for bn128
// address destinationAccount, //account to deposit the tokens to in alicenet
// uint8 ercType,
// uint256 number, // If fungible, this is the amount. If non-fungible, this is the id
// uint256 chainID,
// uint16 poolVersion,
// uint256 nonce
// );

constructor() ImmutableFactory(msg.sender) ImmutableBToken() {}

/**
* takes token deposit calls from ALCB and emits deposit events on token transfer completion
* @param msgSender_ address of account depositing tokens from
* @param poolVersion_ version of pool to deposit token on
* @param depositData_ abi encoded input data that describes the transaction
*/
function forwardDeposit(
address msgSender_,
uint16 poolVersion_,
bytes calldata depositData_
) public onlyBToken returns (uint256 fee) {
//get the router config for the version specified
//get the router address
RouterConfig memory routerConfig = _routerConfig[poolVersion_];
if (routerConfig.routerAddress == address(0))
revert CentralBridgeRouterErrors.InvalidPoolVersion(poolVersion_);
if (routerConfig.notOnline)
revert CentralBridgeRouterErrors.DisabledPoolVersion(
poolVersion_,
routerConfig.routerAddress
);
bytes memory returnDataBytes = IBridgePoolRouter(routerConfig.routerAddress).routeDeposit(
msgSender_,
depositData_
);
DepositReturnData memory returnData = abi.decode(returnDataBytes, (DepositReturnData));
uint256 nonce = _nonce;
for (uint256 i = 0; i < returnData.eventData.length; i++) {
returnData.eventData[i].logData = abi.encodePacked(
returnData.eventData[i].logData,
nonce
);
_emitDepositEvent(returnData.eventData[i].topics, returnData.eventData[i].logData);
nonce += 1;
}
_nonce = nonce;
fee = returnData.fee;
}

/**
* adds a new router to the routerConfig mapping
* @param newRouterAddress_ address of the new router being added
*/
function addRouter(address newRouterAddress_) public onlyFactory {
uint16 version = _routerVersions + 1;
_routerConfig[version] = RouterConfig(newRouterAddress_, false);
//update routerVersions tracker
_routerVersions = version;
}

/**
* allows factory to disable deposits to routers
* @param routerVersion_ version of router to disable
*/
function disableRouter(uint16 routerVersion_) public onlyFactory {
RouterConfig memory config = _routerConfig[routerVersion_];
if (config.routerAddress == address(0))
revert CentralBridgeRouterErrors.InvalidPoolVersion(routerVersion_);
if (config.notOnline) {
revert CentralBridgeRouterErrors.DisabledPoolVersion(
routerVersion_,
config.routerAddress
);
}
_routerConfig[routerVersion_].notOnline = true;
}

/**
* getter function for retrieving number of existing routers
*/
function getRouterCount() public view returns (uint16) {
return _routerVersions;
}

/**
* getter function for getting address of online versioned router
* @param routerVersion_ version of router to query
* @return routerAddress address of versioned router
*/
function getRouterAddress(uint16 routerVersion_) public view returns (address routerAddress) {
RouterConfig memory config = _routerConfig[routerVersion_];
if (config.routerAddress == address(0))
revert CentralBridgeRouterErrors.InvalidPoolVersion(routerVersion_);
routerAddress = config.routerAddress;
}

function _emitDepositEvent(bytes32[] memory topics_, bytes memory eventData_) internal {
if (topics_.length == 1) _log1Event(topics_, eventData_);
else if (topics_.length == 2) _log2Event(topics_, eventData_);
else if (topics_.length == 3) _log3Event(topics_, eventData_);
else if (topics_.length == 4) _log4Event(topics_, eventData_);
else revert CentralBridgeRouterErrors.MissingEventSignature();
}

function _log1Event(bytes32[] memory topics_, bytes memory eventData_) internal {
bytes32 topic0 = topics_[0];
assembly {
log1(add(eventData_, 0x20), mload(eventData_), topic0)
}
}

function _log2Event(bytes32[] memory topics_, bytes memory eventData_) internal {
bytes32 topic0 = topics_[0];
bytes32 topic1 = topics_[1];
assembly {
log2(add(eventData_, 0x20), mload(eventData_), topic0, topic1)
}
}

function _log3Event(bytes32[] memory topics_, bytes memory eventData_) internal {
bytes32 topic0 = topics_[0];
bytes32 topic1 = topics_[1];
bytes32 topic2 = topics_[2];
assembly {
log3(add(eventData_, 0x20), mload(eventData_), topic0, topic1, topic2)
}
}

function _log4Event(bytes32[] memory topics_, bytes memory eventData_) internal {
bytes32 topic0 = topics_[0];
bytes32 topic1 = topics_[1];
bytes32 topic2 = topics_[2];
bytes32 topic3 = topics_[3];
assembly {
log4(add(eventData_, 0x20), mload(eventData_), topic0, topic1, topic2, topic3)
}
}

/* function _isValidVersion(uint16 version_) internal view returns (bool) {
RouterConfig memory config = _routerConfig[version_];
if (config.routerAddress == address(0) || config.notOnline) return false;
return true;
} */
}
6 changes: 6 additions & 0 deletions bridge/contracts/interfaces/IBridgePoolRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.16;

interface IBridgePoolRouter {
function routeDeposit(address account, bytes calldata data) external returns (bytes memory);
}
10 changes: 0 additions & 10 deletions bridge/contracts/interfaces/IBridgeRouter.sol

This file was deleted.

31 changes: 31 additions & 0 deletions bridge/contracts/interfaces/ICentralBridgeRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.16;

interface ICentralBridgeRouter {
struct EventData {
bytes32[] topics;
bytes logData;
}

struct DepositReturnData {
EventData[] eventData;
uint256 fee;
}

struct RouterConfig {
address routerAddress;
bool notOnline;
}

function forwardDeposit(
address msgSender_,
uint16 poolVersion_,
bytes calldata depositData_
) external returns (uint256);

function disableRouter(uint16 routerVersion_) external;

function getRouterCount() external view returns (uint16);

function getRouterAddress(uint16 routerVersion_) external view returns (address);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT-open-group
pragma solidity ^0.8.16;

library CentralBridgeRouterErrors {
error InvalidPoolVersion(uint16 version);
error DisabledPoolVersion(uint16 version, address routerAddress);
error MissingEventSignature();
}
26 changes: 26 additions & 0 deletions bridge/contracts/utils/ImmutableAuth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -531,3 +531,29 @@ abstract contract ImmutableETHDKG is ImmutableFactory {
return 0x455448444b470000000000000000000000000000000000000000000000000000;
}
}

abstract contract ImmutableCentralBridgeRouter is ImmutableFactory {
address private immutable _centralBridgeRouter;
error OnlyCentralBridgeRouter(address sender, address expected);

modifier onlyCentralBridgeRouter() {
if (msg.sender != _centralBridgeRouter) {
revert OnlyCentralBridgeRouter(msg.sender, _centralBridgeRouter);
}
_;
}

constructor() {
_centralBridgeRouter = IAliceNetFactory(_factoryAddress()).lookup(
_saltForCentralBridgeRouter()
);
}

function _centralBridgeRouterAddress() internal view returns (address) {
return _centralBridgeRouter;
}

function _saltForCentralBridgeRouter() internal pure returns (bytes32) {
return 0x43656e7472616c427269646765526f7574657200000000000000000000000000;
}
}
Loading