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
Show all changes
23 commits
Select commit Hold shift + click to select a range
66ba8c4
Remove redundant ABIEncoderV2 pragma (#539)
May 9, 2022
963103b
Viatrix/fee handler (#519)
viatrix May 11, 2022
65dc0bb
use updated geth flags (#511)
waymobetta May 13, 2022
6bcfdb1
Remove ignored visibility for constructor (#552)
May 23, 2022
1da71c4
Remove voting logic + add logic for MPC (#544)
nmlinaric Jun 2, 2022
57648f9
Remove SafeMath for uint256 (#555)
Jun 2, 2022
f856f3a
Release v3.0.0
P1sar Jun 6, 2022
6100d61
Fix which contract artifacts are published (#570)
nmlinaric Jun 7, 2022
34cf568
Release v3.0.1 (#572)
nmlinaric Jun 7, 2022
b5c335f
Add `retry` function (#574)
nmlinaric Jun 20, 2022
3bcbce5
Remove revert on fail for `GenericHandler` (#575)
nmlinaric Jun 21, 2022
5811ad4
Add `executeProposals` function + switch to `abi.encode` (#578)
nmlinaric Jul 1, 2022
3be61a7
Add `destinationDomainID` to signature in `executeProposals` function…
nmlinaric Jul 6, 2022
726c476
Bridge admin access segregator (#585)
Jul 6, 2022
9cd2120
Fix Bridge descriptions after access segregation (#589)
nmlinaric Jul 12, 2022
d88949e
Add `renouceAdmin` function (#592)
nmlinaric Jul 12, 2022
aa9614c
Add `FeeHandlerRouter` (#588)
nmlinaric Jul 14, 2022
35a3e8e
Update `refreshKey` event (#596)
nmlinaric Jul 14, 2022
aa22b0c
release 3.1.0 (#597)
P1sar Jul 14, 2022
e7b9550
Update README.md
P1sar Jul 14, 2022
2dae401
Fix burn from not owner (#614)
viatrix Aug 13, 2022
d97190c
Fix setResource func description (#618)
nmlinaric Aug 19, 2022
0a642f0
Bump rollup from 2.67.2 to 2.79.0
dependabot[bot] Aug 31, 2022
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
5 changes: 2 additions & 3 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 Expand Up @@ -55,8 +53,9 @@ contract ERC721Safe {
@param tokenAddress Address of ERC721 to burn.
@param tokenID ID of token to burn.
*/
function burnERC721(address tokenAddress, uint256 tokenID) internal {
function burnERC721(address tokenAddress, address owner, uint256 tokenID) internal {
ERC721MinterBurnerPauser erc721 = ERC721MinterBurnerPauser(tokenAddress);
require(erc721.ownerOf(tokenID) == owner, 'Burn not from owner');
erc721.burn(tokenID);
}

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
5 changes: 2 additions & 3 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 Expand Up @@ -58,7 +57,7 @@ contract ERC721Handler is IDepositExecute, HandlerHelpers, ERC721Safe {
}

if (_burnList[tokenAddress]) {
burnERC721(tokenAddress, tokenID);
burnERC721(tokenAddress, depositer, tokenID);
} else {
lockERC721(tokenAddress, depositer, address(this), tokenID);
}
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);
}
}
14 changes: 8 additions & 6 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 All @@ -49,9 +50,7 @@ contract GenericHandler is IGenericHandler {
}

/**
@notice First verifies {_resourceIDToContractAddress}[{resourceID}] and
{_contractAddressToResourceID}[{contractAddress}] are not already set,
then sets {_resourceIDToContractAddress} with {contractAddress},
@notice Sets {_resourceIDToContractAddress} with {contractAddress},
{_contractAddressToResourceID} with {resourceID},
{_contractAddressToDepositFunctionSignature} with {depositFunctionSig},
{_contractAddressToDepositFunctionDepositerOffset} with {depositFunctionDepositerOffset},
Expand Down Expand Up @@ -141,8 +140,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
8 changes: 3 additions & 5 deletions contracts/handlers/HandlerHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ contract HandlerHelpers is IERCHandler {
_onlyBridge();
_;
}

/**
@param bridgeAddress Contract address of previously deployed Bridge.
*/
constructor(
address bridgeAddress
) public {
) {
_bridgeAddress = bridgeAddress;
}

Expand All @@ -42,9 +42,7 @@ contract HandlerHelpers is IERCHandler {
}

/**
@notice First verifies {_resourceIDToContractAddress}[{resourceID}] and
{_contractAddressToResourceID}[{contractAddress}] are not already set,
then sets {_resourceIDToContractAddress} with {contractAddress},
@notice Sets {_resourceIDToContractAddress} with {contractAddress},
{_contractAddressToResourceID} with {resourceID},
and {_contractWhitelist} to true for {contractAddress}.
@param resourceID ResourceID to be used when making deposits.
Expand Down
Loading