Skip to content

Commit

Permalink
Merge pull request #2 from dl-tokene/feature/bridging-operation-type
Browse files Browse the repository at this point in the history
  • Loading branch information
Arvolear authored Sep 30, 2024
2 parents d67aee0 + ec25455 commit 88447c2
Show file tree
Hide file tree
Showing 37 changed files with 796 additions and 338 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ coverage

# Typechain generated files
generated-types
go-bindings
55 changes: 38 additions & 17 deletions contracts/bridge/Bridge.sol
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";

import "../interfaces/bridge/IBridge.sol";
import {IBridge} from "../interfaces/bridge/IBridge.sol";

import "../handlers/ERC20Handler.sol";
import "../handlers/ERC721Handler.sol";
import "../handlers/ERC1155Handler.sol";
import "../handlers/NativeHandler.sol";
import {ERC20Handler} from "../handlers/ERC20Handler.sol";
import {ERC721Handler} from "../handlers/ERC721Handler.sol";
import {ERC1155Handler} from "../handlers/ERC1155Handler.sol";
import {NativeHandler} from "../handlers/NativeHandler.sol";

import "../utils/Signers.sol";
import "../utils/Hashes.sol";
import {Signers} from "../utils/Signers.sol";
import {Hashes} from "../utils/Hashes.sol";

/**
* @title Bridge Contract
*/
contract Bridge is
IBridge,
UUPSUpgradeable,
Expand All @@ -30,15 +33,21 @@ contract Bridge is
__Signers_init(signers_, signaturesThreshold_);
}

/**
* @inheritdoc UUPSUpgradeable
*/
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}

/**
* @inheritdoc IBridge
*/
function withdrawERC20(
address token_,
uint256 amount_,
address receiver_,
bytes32 txHash_,
uint256 txNonce_,
bool isWrapped_,
ERC20BridgingType operationType_,
bytes[] calldata signatures_
) external override {
bytes32 signHash_ = getERC20SignHash(
Expand All @@ -48,23 +57,26 @@ contract Bridge is
txHash_,
txNonce_,
block.chainid,
isWrapped_
operationType_
);

_checkAndUpdateHashes(txHash_, txNonce_);
_checkSignatures(signHash_, signatures_);

_withdrawERC20(token_, amount_, receiver_, isWrapped_);
_withdrawERC20(token_, amount_, receiver_, operationType_);
}

/**
* @inheritdoc IBridge
*/
function withdrawERC721(
address token_,
uint256 tokenId_,
address receiver_,
bytes32 txHash_,
uint256 txNonce_,
string calldata tokenURI_,
bool isWrapped_,
ERC721BridgingType operationType_,
bytes[] calldata signatures_
) external override {
bytes32 signHash_ = getERC721SignHash(
Expand All @@ -75,15 +87,18 @@ contract Bridge is
txNonce_,
block.chainid,
tokenURI_,
isWrapped_
operationType_
);

_checkAndUpdateHashes(txHash_, txNonce_);
_checkSignatures(signHash_, signatures_);

_withdrawERC721(token_, tokenId_, receiver_, tokenURI_, isWrapped_);
_withdrawERC721(token_, tokenId_, receiver_, tokenURI_, operationType_);
}

/**
* @inheritdoc IBridge
*/
function withdrawERC1155(
address token_,
uint256 tokenId_,
Expand All @@ -92,7 +107,7 @@ contract Bridge is
bytes32 txHash_,
uint256 txNonce_,
string calldata tokenURI_,
bool isWrapped_,
ERC1155BridgingType operationType_,
bytes[] calldata signatures_
) external override {
bytes32 signHash_ = getERC1155SignHash(
Expand All @@ -104,15 +119,18 @@ contract Bridge is
txNonce_,
block.chainid,
tokenURI_,
isWrapped_
operationType_
);

_checkAndUpdateHashes(txHash_, txNonce_);
_checkSignatures(signHash_, signatures_);

_withdrawERC1155(token_, tokenId_, amount_, receiver_, tokenURI_, isWrapped_);
_withdrawERC1155(token_, tokenId_, amount_, receiver_, tokenURI_, operationType_);
}

/**
* @inheritdoc IBridge
*/
function withdrawNative(
uint256 amount_,
address receiver_,
Expand All @@ -134,6 +152,9 @@ contract Bridge is
_withdrawNative(amount_, receiver_);
}

/**
* @notice The function to add a new hash
*/
function addHash(bytes32 txHash_, uint256 txNonce_) external onlyOwner {
_checkAndUpdateHashes(txHash_, txNonce_);
}
Expand Down
29 changes: 19 additions & 10 deletions contracts/handlers/ERC1155Handler.sol
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";

import "../interfaces/handlers/IERC1155Handler.sol";
import "../interfaces/tokens/IERC1155MintableBurnable.sol";
import {IERC1155Handler} from "../interfaces/handlers/IERC1155Handler.sol";
import {IERC1155MintableBurnable} from "../interfaces/tokens/IERC1155MintableBurnable.sol";

/**
* @title ERC1155Handler
*/
abstract contract ERC1155Handler is IERC1155Handler, ERC1155Holder {
/**
* @inheritdoc IERC1155Handler
*/
function depositERC1155(
address token_,
uint256 tokenId_,
uint256 amount_,
string calldata receiver_,
string calldata network_,
bool isWrapped_
ERC1155BridgingType operationType_
) external override {
require(token_ != address(0), "ERC1155Handler: zero token");
require(amount_ > 0, "ERC1155Handler: amount is zero");

IERC1155MintableBurnable erc1155_ = IERC1155MintableBurnable(token_);

if (isWrapped_) {
if (operationType_ == ERC1155BridgingType.Wrapped) {
erc1155_.burnFrom(msg.sender, tokenId_, amount_);
} else {
erc1155_.safeTransferFrom(msg.sender, address(this), tokenId_, amount_, "");
}

emit DepositedERC1155(token_, tokenId_, amount_, receiver_, network_, isWrapped_);
emit DepositedERC1155(token_, tokenId_, amount_, receiver_, network_, operationType_);
}

function _withdrawERC1155(
Expand All @@ -35,21 +41,24 @@ abstract contract ERC1155Handler is IERC1155Handler, ERC1155Holder {
uint256 amount_,
address receiver_,
string calldata tokenURI_,
bool isWrapped_
ERC1155BridgingType operationType_
) internal {
require(token_ != address(0), "ERC1155Handler: zero token");
require(receiver_ != address(0), "ERC1155Handler: zero receiver");
require(amount_ > 0, "ERC1155Handler: amount is zero");

IERC1155MintableBurnable erc1155_ = IERC1155MintableBurnable(token_);

if (isWrapped_) {
if (operationType_ == ERC1155BridgingType.Wrapped) {
erc1155_.mintTo(receiver_, tokenId_, amount_, tokenURI_);
} else {
erc1155_.safeTransferFrom(address(this), receiver_, tokenId_, amount_, "");
}
}

/**
* @inheritdoc IERC1155Handler
*/
function getERC1155SignHash(
address token_,
uint256 tokenId_,
Expand All @@ -59,7 +68,7 @@ abstract contract ERC1155Handler is IERC1155Handler, ERC1155Holder {
uint256 txNonce_,
uint256 chainId_,
string calldata tokenURI_,
bool isWrapped_
ERC1155BridgingType operationType_
) public pure returns (bytes32) {
return
keccak256(
Expand All @@ -72,7 +81,7 @@ abstract contract ERC1155Handler is IERC1155Handler, ERC1155Holder {
txNonce_,
chainId_,
tokenURI_,
isWrapped_
operationType_
)
);
}
Expand Down
36 changes: 26 additions & 10 deletions contracts/handlers/ERC20Handler.sol
Original file line number Diff line number Diff line change
@@ -1,62 +1,78 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

import "../interfaces/tokens/IERC20MintableBurnable.sol";
import "../interfaces/handlers/IERC20Handler.sol";
import {IUSDCType} from "../interfaces/tokens/IUSDCType.sol";
import {IERC20Handler} from "../interfaces/handlers/IERC20Handler.sol";
import {IERC20MintableBurnable} from "../interfaces/tokens/IERC20MintableBurnable.sol";

/**
* @title ERC20Handler
*/
abstract contract ERC20Handler is IERC20Handler {
using SafeERC20 for IERC20MintableBurnable;

/**
* @inheritdoc IERC20Handler
*/
function depositERC20(
address token_,
uint256 amount_,
string calldata receiver_,
string calldata network_,
bool isWrapped_
ERC20BridgingType operationType_
) external override {
require(token_ != address(0), "ERC20Handler: zero token");
require(amount_ > 0, "ERC20Handler: amount is zero");

IERC20MintableBurnable erc20_ = IERC20MintableBurnable(token_);

if (isWrapped_) {
if (operationType_ == ERC20BridgingType.Wrapped) {
erc20_.burnFrom(msg.sender, amount_);
} else {
erc20_.safeTransferFrom(msg.sender, address(this), amount_);
}

emit DepositedERC20(token_, amount_, receiver_, network_, isWrapped_);
if (operationType_ == ERC20BridgingType.USDCType) {
IUSDCType(token_).burn(amount_);
}

emit DepositedERC20(token_, amount_, receiver_, network_, operationType_);
}

function _withdrawERC20(
address token_,
uint256 amount_,
address receiver_,
bool isWrapped_
ERC20BridgingType operationType_
) internal {
require(token_ != address(0), "ERC20Handler: zero token");
require(amount_ > 0, "ERC20Handler: amount is zero");
require(receiver_ != address(0), "ERC20Handler: zero receiver");

IERC20MintableBurnable erc20_ = IERC20MintableBurnable(token_);

if (isWrapped_) {
if (operationType_ == ERC20BridgingType.Wrapped) {
erc20_.mintTo(receiver_, amount_);
} else if (operationType_ == ERC20BridgingType.USDCType) {
IUSDCType(token_).mint(receiver_, amount_);
} else {
erc20_.safeTransfer(receiver_, amount_);
}
}

/**
* @inheritdoc IERC20Handler
*/
function getERC20SignHash(
address token_,
uint256 amount_,
address receiver_,
bytes32 txHash_,
uint256 txNonce_,
uint256 chainId_,
bool isWrapped_
ERC20BridgingType operationType_
) public pure returns (bytes32) {
return
keccak256(
Expand All @@ -67,7 +83,7 @@ abstract contract ERC20Handler is IERC20Handler {
txHash_,
txNonce_,
chainId_,
isWrapped_
operationType_
)
);
}
Expand Down
Loading

0 comments on commit 88447c2

Please sign in to comment.