This repository has been archived by the owner on May 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 166
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add erc1155Handler, erc1155Safe, and modify HandlerHelpers (#416)
* add erc1155Handler, erc1155Safe, and modify HandlerHelpers * update old version withdraw functions * add using normal address in handler withdraw * add comments * modify withdraw test and add tests for erc1155
- Loading branch information
1 parent
cbfaf9c
commit 6869c8d
Showing
13 changed files
with
662 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
pragma solidity 0.6.12; | ||
|
||
import "@openzeppelin/contracts/math/SafeMath.sol"; | ||
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; | ||
import "@openzeppelin/contracts/token/ERC1155/ERC1155Burnable.sol"; | ||
import "@openzeppelin/contracts/presets/ERC1155PresetMinterPauser.sol"; | ||
|
||
/** | ||
@title Manages deposited ERC1155s. | ||
@author ChainSafe Systems. | ||
@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. | ||
@param tokenAddress Address of ERC1155 to transfer. | ||
@param owner Address of current token owner. | ||
@param recipient Address to transfer token to. | ||
@param tokenIDs IDs of tokens to transfer. | ||
@param amounts Amounts of tokens to transfer. | ||
@param data Additional data. | ||
*/ | ||
function lockBatchERC1155(address tokenAddress, address owner, address recipient, uint[] memory tokenIDs, uint[] memory amounts, bytes memory data) internal { | ||
IERC1155 erc1155 = IERC1155(tokenAddress); | ||
erc1155.safeBatchTransferFrom(owner, recipient, tokenIDs, amounts, data); | ||
} | ||
|
||
/** | ||
@notice Transfers custody of token to recipient with batching. | ||
@param tokenAddress Address of ERC1155 to transfer. | ||
@param owner Address of current token owner. | ||
@param recipient Address to transfer token to. | ||
@param tokenIDs IDs of tokens to transfer. | ||
@param amounts Amounts of tokens to transfer. | ||
@param data Additional data. | ||
*/ | ||
function releaseBatchERC1155(address tokenAddress, address owner, address recipient, uint256[] memory tokenIDs, uint[] memory amounts, bytes memory data) internal { | ||
IERC1155 erc1155 = IERC1155(tokenAddress); | ||
erc1155.safeBatchTransferFrom(owner, recipient, tokenIDs, amounts, data); | ||
} | ||
|
||
/** | ||
@notice Used to create new ERC1155s with batching. | ||
@param tokenAddress Address of ERC1155 to mint. | ||
@param recipient Address to mint token to. | ||
@param tokenIDs IDs of tokens to mint. | ||
@param amounts Amounts of token to mint. | ||
@param data Additional data. | ||
*/ | ||
function mintBatchERC1155(address tokenAddress, address recipient, uint[] memory tokenIDs, uint[] memory amounts, bytes memory data) internal { | ||
ERC1155PresetMinterPauser erc1155 = ERC1155PresetMinterPauser(tokenAddress); | ||
erc1155.mintBatch(recipient, tokenIDs, amounts, data); | ||
} | ||
|
||
/** | ||
@notice Used to burn ERC1155s with batching. | ||
@param tokenAddress Address of ERC1155 to burn. | ||
@param tokenIDs IDs of tokens to burn. | ||
@param amounts Amounts of tokens to burn. | ||
*/ | ||
function burnBatchERC1155(address tokenAddress, address owner, uint[] memory tokenIDs, uint[] memory amounts) internal { | ||
ERC1155Burnable erc1155 = ERC1155Burnable(tokenAddress); | ||
erc1155.burnBatch(owner, tokenIDs, amounts); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
pragma solidity 0.6.12; | ||
pragma experimental ABIEncoderV2; | ||
|
||
import "../interfaces/IDepositExecute.sol"; | ||
import "./HandlerHelpers.sol"; | ||
import "../ERC1155Safe.sol"; | ||
import "@openzeppelin/contracts/introspection/ERC165Checker.sol"; | ||
import "@openzeppelin/contracts/token/ERC1155/ERC1155Holder.sol"; | ||
import "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol"; | ||
|
||
contract ERC1155Handler is IDepositExecute, HandlerHelpers, ERC1155Safe, ERC1155Holder { | ||
using ERC165Checker for address; | ||
|
||
bytes4 private constant _INTERFACE_ERC1155_METADATA = 0x0e89341c; | ||
bytes private constant EMPTY_BYTES = ""; | ||
|
||
/** | ||
@param bridgeAddress Contract address of previously deployed Bridge. | ||
*/ | ||
constructor( | ||
address bridgeAddress | ||
) public HandlerHelpers(bridgeAddress) { | ||
} | ||
|
||
/** | ||
@notice A deposit is initiatied by making a deposit in the Bridge contract. | ||
@param resourceID ResourceID used to find address of token to be used for deposit. | ||
@param depositer Address of account making the deposit in the Bridge contract. | ||
@param data Consists of ABI-encoded arrays of tokenIDs and amounts. | ||
*/ | ||
function deposit(bytes32 resourceID, address depositer, bytes calldata data) external override onlyBridge returns (bytes memory metaData) { | ||
uint[] memory tokenIDs; | ||
uint[] memory amounts; | ||
|
||
(tokenIDs, amounts) = abi.decode(data, (uint[], uint[])); | ||
|
||
address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; | ||
require(tokenAddress != address(0), "provided resourceID does not exist"); | ||
|
||
if (_burnList[tokenAddress]) { | ||
burnBatchERC1155(tokenAddress, depositer, tokenIDs, amounts); | ||
} else { | ||
lockBatchERC1155(tokenAddress, depositer, address(this), tokenIDs, amounts, EMPTY_BYTES); | ||
} | ||
} | ||
|
||
/** | ||
@notice Proposal execution should be initiated when a proposal is finalized in the Bridge contract. | ||
by a relayer on the deposit's destination chain. | ||
@param data Consists of ABI-encoded {tokenIDs}, {amounts}, {recipient}, | ||
and {transferData} of types uint[], uint[], bytes, bytes. | ||
*/ | ||
function executeProposal(bytes32 resourceID, bytes calldata data) external override onlyBridge { | ||
uint[] memory tokenIDs; | ||
uint[] memory amounts; | ||
bytes memory recipient; | ||
bytes memory transferData; | ||
|
||
(tokenIDs, amounts, recipient, transferData) = abi.decode(data, (uint[], uint[], bytes, bytes)); | ||
|
||
bytes20 recipientAddress; | ||
|
||
assembly { | ||
recipientAddress := mload(add(recipient, 0x20)) | ||
} | ||
|
||
address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; | ||
require(_contractWhitelist[address(tokenAddress)], "provided tokenAddress is not whitelisted"); | ||
|
||
if (_burnList[tokenAddress]) { | ||
mintBatchERC1155(tokenAddress, address(recipientAddress), tokenIDs, amounts, transferData); | ||
} else { | ||
releaseBatchERC1155(tokenAddress, address(this), address(recipientAddress), tokenIDs, amounts, transferData); | ||
} | ||
} | ||
|
||
/** | ||
@notice Used to manually release ERC1155 tokens from ERC1155Safe. | ||
@param data Consists of ABI-encoded {tokenAddress}, {recipient}, {tokenIDs}, | ||
{amounts}, and {transferData} of types address, address, uint[], uint[], bytes. | ||
*/ | ||
function withdraw(bytes memory data) external override onlyBridge { | ||
address tokenAddress; | ||
address recipient; | ||
uint[] memory tokenIDs; | ||
uint[] memory amounts; | ||
bytes memory transferData; | ||
|
||
(tokenAddress, recipient, tokenIDs, amounts, transferData) = abi.decode(data, (address, address, uint[], uint[], bytes)); | ||
|
||
releaseBatchERC1155(tokenAddress, address(this), recipient, tokenIDs, amounts, transferData); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.