文件 1 的 13:BearsDeluxeI.sol
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
abstract contract BearsDeluxeI is Ownable, IERC721 {
function mint(address _owner, uint256 _tokenId) external virtual;
function exists(uint256 _tokenId) external view virtual returns (bool);
function getMaxSupply() external virtual returns (uint256);
function tokensOfOwner(address _owner) external view virtual returns (uint256[] memory);
}
文件 2 的 13:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 13:DeluxeBridge.sol
pragma solidity ^0.8.9;
import "../interfaces/BearsDeluxeI.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract DeluxeBridge is ERC1155Holder, Ownable, ReentrancyGuard {
uint32 public totalBridged;
uint256[] public idsReceived;
uint16[] public idsBridged;
bool public bridgingEnabled;
mapping(uint256 => address) public idsAndSenders;
mapping(address => uint256[]) public sendersAndIds;
mapping(address => uint256[]) public oldsIdsBridgedBySender;
bytes32 private merkleRoot;
IERC1155 public osContract;
BearsDeluxeI public bdContract;
event ReceivedFromOS(address indexed _sender, address indexed _receiver, uint256 indexed _tokenId, uint256 _amount);
event ReceivedFrom721(address indexed _sender, address indexed _receiver, uint256 indexed _tokenId);
event Minted721(address indexed _sender, uint256 indexed _tokenId);
event ToggleBridging(bool _enabled);
event Transferred1155(address indexed _to, uint256 indexed _tokenId);
constructor() {}
function onERC1155Received(
address _sender,
address _receiver,
uint256 _tokenId,
uint256 _amount,
bytes memory _data
) public override nonReentrant returns (bytes4) {
require(msg.sender == address(osContract), "Forbidden");
require(!bridgingEnabled, "Bridging is stopped");
triggerReceived1155(_sender, _tokenId);
emit ReceivedFromOS(_sender, _receiver, _tokenId, _amount);
return super.onERC1155Received(_sender, _receiver, _tokenId, _amount, _data);
}
function claim(
uint256 _oldId,
uint16 _newId,
bytes32 _leaf,
bytes32[] calldata _merkleProof
) external nonReentrant {
require(!bridgingEnabled, "Bridging is stopped");
bytes32 node = keccak256(abi.encodePacked(_oldId, _newId));
require(node == _leaf, "Leaf not matching the node");
require(MerkleProof.verify(_merkleProof, merkleRoot, _leaf), "Invalid proof.");
require(idsAndSenders[_oldId] == msg.sender, "Not owner of OS id");
totalBridged++;
idsBridged.push(_newId);
oldsIdsBridgedBySender[msg.sender].push(_oldId);
mintOnClaiming(msg.sender, _newId);
}
function mint721(uint16 _tokenId, address _to) external onlyOwner {
require(_to != address(0), "Mint to address 0");
require(!bdContract.exists(_tokenId), "Token exists");
if (bdContract.exists(_tokenId) && bdContract.ownerOf(_tokenId) == address(this)) {
bdContract.safeTransferFrom(address(this), _to, _tokenId);
return;
}
_mint721(_tokenId, _to);
}
function transfer721(uint256 _tokenId, address _owner) external onlyOwner {
require(_owner != address(0), "Can not send to address 0");
bdContract.safeTransferFrom(address(this), _owner, _tokenId);
}
function _mint721(uint16 _tokenId, address _owner) private {
bdContract.mint(_owner, uint16(_tokenId));
emit Minted721(_owner, _tokenId);
}
function triggerReceived1155(address _sender, uint256 _tokenId) internal {
require(_sender != address(0), "Update from address 0");
idsReceived.push(_tokenId);
idsAndSenders[_tokenId] = _sender;
sendersAndIds[_sender].push(_tokenId);
}
function mintOnClaiming(address _sender, uint16 _tokenId) internal returns (bool) {
require(_sender != address(0), "Can not mint to address 0");
require(_tokenId != 0, "New token id !exists");
require(!bdContract.exists(_tokenId), "Token already minted");
bdContract.mint(_sender, _tokenId);
emit Minted721(_sender, _tokenId);
return true;
}
function setBDContract(address _contract) external onlyOwner {
require(_contract != address(0), "_contract !address 0");
bdContract = BearsDeluxeI(_contract);
}
function setOSContract(address _contract) external onlyOwner {
require(_contract != address(0), "_contract !address 0");
osContract = IERC1155(_contract);
}
function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
merkleRoot = _merkleRoot;
}
function checkBalance(address _collector, uint256 _tokenId) external view returns (uint256) {
require(_collector != address(0), "_collector is address 0");
return osContract.balanceOf(_collector, _tokenId);
}
function getTransferredByCollector(address _collector) external view returns (uint256[] memory) {
require(_collector != address(0), "_collector is address 0");
return sendersAndIds[_collector];
}
function getBridgedByCollector(address _collector) external view returns (uint256[] memory) {
require(_collector != address(0), "_collector is address 0");
return oldsIdsBridgedBySender[_collector];
}
function getMerkleRoot() external view onlyOwner returns (bytes32) {
return merkleRoot;
}
function getTokenBridgedCount() external view returns (uint128) {
return totalBridged;
}
function getBridgedTokens() external view returns (uint16[] memory) {
return idsBridged;
}
function getIdsTransfered() external view returns (uint256[] memory) {
return idsReceived;
}
function getBDContract() external view returns (address) {
return address(bdContract);
}
function getOSContract() external view returns (address) {
return address(osContract);
}
function transfer1155(uint256 _tokenId, address _owner) external onlyOwner nonReentrant {
require(_owner != address(0), "Can not send to address 0");
osContract.safeTransferFrom(address(this), _owner, _tokenId, 1, "");
emit Transferred1155(_owner, _tokenId);
}
function toggleBridging(bool _enabled) external onlyOwner {
bridgingEnabled = _enabled;
emit ToggleBridging(_enabled);
}
}
文件 4 的 13:ERC1155Holder.sol
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 5 的 13:ERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
文件 6 的 13:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 7 的 13:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 8 的 13:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 9 的 13:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 13:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 11 的 13:MerkleProof.sol
pragma solidity ^0.8.0;
library MerkleProof {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
}
return computedHash == root;
}
}
文件 12 的 13:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_setOwner(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 13 的 13:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
{
"compilationTarget": {
"contracts/core/DeluxeBridge.sol": "DeluxeBridge"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Minted721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"address","name":"_receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ReceivedFrom721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"address","name":"_receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"ReceivedFromOS","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_enabled","type":"bool"}],"name":"ToggleBridging","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Transferred1155","type":"event"},{"inputs":[],"name":"bdContract","outputs":[{"internalType":"contract BearsDeluxeI","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collector","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"checkBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_oldId","type":"uint256"},{"internalType":"uint16","name":"_newId","type":"uint16"},{"internalType":"bytes32","name":"_leaf","type":"bytes32"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBDContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collector","type":"address"}],"name":"getBridgedByCollector","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBridgedTokens","outputs":[{"internalType":"uint16[]","name":"","type":"uint16[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getIdsTransfered","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOSContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenBridgedCount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collector","type":"address"}],"name":"getTransferredByCollector","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"idsAndSenders","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"idsBridged","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"idsReceived","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"},{"internalType":"address","name":"_to","type":"address"}],"name":"mint721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"oldsIdsBridgedBySender","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"osContract","outputs":[{"internalType":"contract IERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"sendersAndIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setBDContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setOSContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"toggleBridging","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalBridged","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"transfer1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"transfer721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]