Skip to content
This repository was archived by the owner on May 9, 2024. It is now read-only.
Closed
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ coverage.json
src/ethers
src/web3
ganache-cli/
dist/
dist/
.vscode/
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# chainbridge-solidity
# sygma-solidity

[![Coverage Status](https://coveralls.io/repos/github/ChainSafe/chainbridge-solidity/badge.svg?branch=master)](https://coveralls.io/github/ChainSafe/chainbridge-solidity?branch=master)

ChainBridge uses Solidity smart contracts to enable transfers to and from EVM compatible chains. These contracts consist of a core bridge contract (Bridge.sol) and a set of handler contracts (ERC20Handler.sol, ERC721Handler.sol, and GenericHandler.sol). The bridge contract is responsible for initiating, voting on, and executing proposed transfers. The handlers are used by the bridge contract to interact with other existing contracts.
Sygma uses Solidity smart contracts to enable transfers to and from EVM compatible chains. These contracts consist of a core bridge contract (Bridge.sol) and a set of handler contracts (ERC20Handler.sol, ERC721Handler.sol, and GenericHandler.sol). The bridge contract is responsible for initiating, voting on, and executing proposed transfers. The handlers are used by the bridge contract to interact with other existing contracts.

Read more [here](https://chainbridge.chainsafe.io/).
Read more [here](https://chainsafe.io/).

A CLI to deploy and interact with these contracts can be found [here](https://github.com/ChainSafe/chainbridge-deploy/tree/master/cb-sol-cli).

Expand Down
491 changes: 188 additions & 303 deletions contracts/Bridge.sol

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion contracts/CentrifugeAsset.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;
pragma experimental ABIEncoderV2;

/**
@title Represents a bridged Centrifuge asset.
Expand Down
2 changes: 0 additions & 2 deletions contracts/ERC1155Safe.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
import "@openzeppelin/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol";
Expand All @@ -12,7 +11,6 @@ import "@openzeppelin/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.
@notice This contract is intended to be used with ERC1155Handler contract.
*/
contract ERC1155Safe {
using SafeMath for uint256;

/**
@notice Used to gain custoday of deposited token with batching.
Expand Down
2 changes: 0 additions & 2 deletions contracts/ERC20Safe.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
Expand All @@ -12,7 +11,6 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
@notice This contract is intended to be used with ERC20Handler contract.
*/
contract ERC20Safe {
using SafeMath for uint256;

/**
@notice Used to gain custody of deposited token.
Expand Down
2 changes: 1 addition & 1 deletion contracts/ERC721MinterBurnerPauser.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ contract ERC721MinterBurnerPauser is Context, AccessControl, ERC721Burnable, ERC
* Token URIs will be autogenerated based on `baseURI` and their token IDs.
* See {ERC721-tokenURI}.
*/
constructor(string memory name, string memory symbol, string memory baseURI) public ERC721(name, symbol) {
constructor(string memory name, string memory symbol, string memory baseURI) ERC721(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

_setupRole(MINTER_ROLE, _msgSender());
Expand Down
2 changes: 0 additions & 2 deletions contracts/ERC721Safe.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./ERC721MinterBurnerPauser.sol";

Expand All @@ -11,7 +10,6 @@ import "./ERC721MinterBurnerPauser.sol";
@notice This contract is intended to be used with ERC721Handler contract.
*/
contract ERC721Safe {
using SafeMath for uint256;

/**
@notice Used to gain custoday of deposited token.
Expand Down
1 change: 0 additions & 1 deletion contracts/Forwarder.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
Expand Down
9 changes: 0 additions & 9 deletions contracts/TestContracts.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;
pragma experimental ABIEncoderV2;

import "./utils/SafeCast.sol";
import "./handlers/HandlerHelpers.sol";

contract NoArgument {
Expand Down Expand Up @@ -45,13 +43,6 @@ contract WithDepositer {
}
}

contract SafeCaster {
using SafeCast for *;

function toUint200(uint input) external pure returns(uint200) {
return input.toUint200();
}
}

contract ReturnData {
function returnData(string memory argument) external pure returns(bytes32 response) {
Expand Down
3 changes: 1 addition & 2 deletions contracts/handlers/ERC1155Handler.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;
pragma experimental ABIEncoderV2;

import "../interfaces/IDepositExecute.sol";
import "./HandlerHelpers.sol";
Expand All @@ -20,7 +19,7 @@ contract ERC1155Handler is IDepositExecute, HandlerHelpers, ERC1155Safe, ERC1155
*/
constructor(
address bridgeAddress
) public HandlerHelpers(bridgeAddress) {
) HandlerHelpers(bridgeAddress) {
}

/**
Expand Down
3 changes: 1 addition & 2 deletions contracts/handlers/ERC20Handler.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;
pragma experimental ABIEncoderV2;

import "../interfaces/IDepositExecute.sol";
import "./HandlerHelpers.sol";
Expand All @@ -17,7 +16,7 @@ contract ERC20Handler is IDepositExecute, HandlerHelpers, ERC20Safe {
*/
constructor(
address bridgeAddress
) public HandlerHelpers(bridgeAddress) {
) HandlerHelpers(bridgeAddress) {
}

/**
Expand Down
3 changes: 1 addition & 2 deletions contracts/handlers/ERC721Handler.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;
pragma experimental ABIEncoderV2;

import "../interfaces/IDepositExecute.sol";
import "./HandlerHelpers.sol";
Expand All @@ -24,7 +23,7 @@ contract ERC721Handler is IDepositExecute, HandlerHelpers, ERC721Safe {
*/
constructor(
address bridgeAddress
) public HandlerHelpers(bridgeAddress) {
) HandlerHelpers(bridgeAddress) {
}

/**
Expand Down
86 changes: 86 additions & 0 deletions contracts/handlers/FeeHandlerRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;
pragma experimental ABIEncoderV2;

import "../interfaces/IFeeHandler.sol";
import "../utils/AccessControl.sol";

/**
@title Handles FeeHandler routing for resources.
@author ChainSafe Systems.
@notice This contract is intended to be used with the Bridge contract.
*/
contract FeeHandlerRouter is IFeeHandler, AccessControl {
address public immutable _bridgeAddress;

// destination domainID => resourceID => feeHandlerAddress
mapping (uint8 => mapping(bytes32 => IFeeHandler)) public _domainResourceIDToFeeHandlerAddress;

event FeeChanged(
uint256 newFee
);

modifier onlyBridge() {
_onlyBridge();
_;
}

function _onlyBridge() private view {
require(msg.sender == _bridgeAddress, "sender must be bridge contract");
}

modifier onlyAdmin() {
_onlyAdmin();
_;
}

function _onlyAdmin() private view {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "sender doesn't have admin role");
}

/**
@param bridgeAddress Contract address of previously deployed Bridge.
*/
constructor(address bridgeAddress) public {
_bridgeAddress = bridgeAddress;
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
/**
@notice Maps the {handlerAddress} to {resourceID} to {destinantionDomainID} in {_domainResourceIDToFeeHandlerAddress}.
@param destinationDomainID ID of chain FeeHandler contracts will be called.
@param resourceID ResourceID for which the corresponding FeeHandler will collect/calcualte fee.
@param handlerAddress Address of FeeHandler which will be called for specified resourceID.
*/
function adminSetResourceHandler(uint8 destinationDomainID, bytes32 resourceID, IFeeHandler handlerAddress) external onlyAdmin {
_domainResourceIDToFeeHandlerAddress[destinationDomainID][resourceID] = handlerAddress;
}


/**
@notice Initiates collecting fee with corresponding fee handler contract using IFeeHandler interface.
@param sender Sender of the deposit.
@param destinationDomainID ID of chain deposit will be bridged to.
@param resourceID ResourceID to be used when making deposits.
@param depositData Additional data to be passed to specified handler.
@param feeData Additional data to be passed to the fee handler.
*/
function collectFee(address sender, uint8 fromDomainID, uint8 destinationDomainID, bytes32 resourceID, bytes calldata depositData, bytes calldata feeData) payable external onlyBridge {
IFeeHandler feeHandler = _domainResourceIDToFeeHandlerAddress[destinationDomainID][resourceID];
feeHandler.collectFee{value: msg.value}(sender, fromDomainID, destinationDomainID, resourceID, depositData, feeData);
}

/**
@notice Initiates calculating fee with corresponding fee handler contract using IFeeHandler interface.
@param sender Sender of the deposit.
@param destinationDomainID ID of chain deposit will be bridged to.
@param resourceID ResourceID to be used when making deposits.
@param depositData Additional data to be passed to specified handler.
@param feeData Additional data to be passed to the fee handler.
@return fee Returns the fee amount.
@return tokenAddress Returns the address of the token to be used for fee.
*/
function calculateFee(address sender, uint8 fromDomainID, uint8 destinationDomainID, bytes32 resourceID, bytes calldata depositData, bytes calldata feeData) external view returns(uint256 fee, address tokenAddress) {
IFeeHandler feeHandler = _domainResourceIDToFeeHandlerAddress[destinationDomainID][resourceID];
return feeHandler.calculateFee(sender, fromDomainID, destinationDomainID, resourceID, depositData, feeData);
}
}
10 changes: 7 additions & 3 deletions contracts/handlers/GenericHandler.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.11;
pragma experimental ABIEncoderV2;

import "../interfaces/IGenericHandler.sol";

Expand Down Expand Up @@ -30,6 +29,8 @@ contract GenericHandler is IGenericHandler {
// token contract address => is whitelisted
mapping (address => bool) public _contractWhitelist;

event FailedHandlerExecution();

modifier onlyBridge() {
_onlyBridge();
_;
Expand Down Expand Up @@ -141,8 +142,11 @@ contract GenericHandler is IGenericHandler {
bytes4 sig = _contractAddressToExecuteFunctionSignature[contractAddress];
if (sig != bytes4(0)) {
bytes memory callData = abi.encodePacked(sig, metaData);
(bool success,) = contractAddress.call(callData);
require(success, "delegatecall to contractAddress failed");
(bool success, ) = contractAddress.call(callData);

if (!success) {
emit FailedHandlerExecution();
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/handlers/HandlerHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ contract HandlerHelpers is IERCHandler {
*/
constructor(
address bridgeAddress
) public {
) {
_bridgeAddress = bridgeAddress;
}

Expand Down
Loading