编译器
0.8.21+commit.d9974bed
文件 1 的 28:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 28: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 的 28: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;
}
}
文件 4 的 28: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);
}
}
文件 5 的 28: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;
}
}
文件 6 的 28:ERC721Holder.sol
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
contract ERC721Holder is IERC721Receiver {
function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
文件 7 的 28:IAdvancedWhiteList.sol
pragma solidity 0.8.21;
import "../contracts/LibEnvelopTypes.sol";
interface IAdvancedWhiteList {
event WhiteListItemChanged(
address indexed asset,
bool enabledForFee,
bool enabledForCollateral,
bool enabledRemoveFromCollateral,
address transferFeeModel
);
event BlackListItemChanged(
address indexed asset,
bool isBlackListed
);
function getWLItem(address _asset) external view returns (ETypes.WhiteListItem memory);
function getWLItemCount() external view returns (uint256);
function getBLItem(address _asset) external view returns (bool);
function getBLItemCount() external view returns (uint256);
function enabledForCollateral(address _asset) external view returns (bool);
function enabledForFee(address _asset) external view returns (bool);
function enabledRemoveFromCollateral(address _asset) external view returns (bool);
function rulesEnabled(address _asset, bytes2 _rules) external view returns (bool);
function validateRules(address _asset, bytes2 _rules) external view returns (bytes2);
}
文件 8 的 28: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;
}
文件 9 的 28:IERC1155MetadataURI.sol
pragma solidity ^0.8.0;
import "../IERC1155.sol";
interface IERC1155MetadataURI is IERC1155 {
function uri(uint256 id) external view returns (string memory);
}
文件 10 的 28:IERC1155Mintable.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
interface IERC1155Mintable is IERC1155MetadataURI {
function mint(address _to, uint256 _tokenId, uint256 _amount) external;
function burn(address _to, uint256 _tokenId, uint256 _amount) external;
function totalSupply(uint256 _id) external view returns (uint256);
function exists(uint256 _tokenId) external view returns(bool);
}
文件 11 的 28: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);
}
文件 12 的 28:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 13 的 28:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 14 的 28:IERC20Extended.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IERC20Extended is IERC20 {
function mint(address _to, uint256 _value) external;
}
文件 15 的 28:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 16 的 28: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, bytes calldata data) external;
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 setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 17 的 28:IERC721Metadata.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 18 的 28:IERC721Mintable.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
interface IERC721Mintable is IERC721Metadata {
function mint(address _to, uint256 _tokenId) external;
function burn(uint256 _tokenId) external;
function exists(uint256 _tokenId) external view returns(bool);
}
文件 19 的 28:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 20 的 28:IFeeRoyaltyModel.sol
pragma solidity 0.8.21;
import "../contracts/LibEnvelopTypes.sol";
interface IFeeRoyaltyModel {
function registerModel() external;
function getTransfersList(
ETypes.Fee calldata _fee,
ETypes.Royalty[] calldata _royalties,
address _from,
address _to
) external view returns (
ETypes.AssetItem[] memory,
address[] memory,
address[] memory
);
function wrapper() external returns (address);
}
文件 21 的 28:IWrapper.sol
pragma solidity 0.8.21;
import "../contracts/LibEnvelopTypes.sol";
interface IWrapper {
event WrappedV1(
address indexed inAssetAddress,
address indexed outAssetAddress,
uint256 indexed inAssetTokenId,
uint256 outTokenId,
address wnftFirstOwner,
uint256 nativeCollateralAmount,
bytes2 rules
);
event UnWrappedV1(
address indexed wrappedAddress,
address indexed originalAddress,
uint256 indexed wrappedId,
uint256 originalTokenId,
address beneficiary,
uint256 nativeCollateralAmount,
bytes2 rules
);
event CollateralAdded(
address indexed wrappedAddress,
uint256 indexed wrappedId,
uint8 assetType,
address collateralAddress,
uint256 collateralTokenId,
uint256 collateralBalance
);
event PartialUnWrapp(
address indexed wrappedAddress,
uint256 indexed wrappedId,
uint256 lastCollateralIndex
);
event SuspiciousFail(
address indexed wrappedAddress,
uint256 indexed wrappedId,
address indexed failedContractAddress
);
event EnvelopFee(
address indexed receiver,
address indexed wNFTConatract,
uint256 indexed wNFTTokenId,
uint256 amount
);
function wrap(
ETypes.INData calldata _inData,
ETypes.AssetItem[] calldata _collateral,
address _wrappFor
)
external
payable
returns (ETypes.AssetItem memory);
function addCollateral(
address _wNFTAddress,
uint256 _wNFTTokenId,
ETypes.AssetItem[] calldata _collateral
) external payable;
function unWrap(
address _wNFTAddress,
uint256 _wNFTTokenId
) external;
function unWrap(
ETypes.AssetType _wNFTType,
address _wNFTAddress,
uint256 _wNFTTokenId
) external;
function unWrap(
ETypes.AssetType _wNFTType,
address _wNFTAddress,
uint256 _wNFTTokenId,
bool _isEmergency
) external;
function chargeFees(
address _wNFTAddress,
uint256 _wNFTTokenId,
address _from,
address _to,
bytes1 _feeType
)
external
returns (bool);
function MAX_COLLATERAL_SLOTS() external view returns (uint256);
function protocolTechToken() external view returns (address);
function protocolWhiteList() external view returns (address);
function getWrappedToken(address _wNFTAddress, uint256 _wNFTTokenId)
external
view
returns (ETypes.WNFT memory);
function getOriginalURI(address _wNFTAddress, uint256 _wNFTTokenId)
external
view
returns(string memory);
function getCollateralBalanceAndIndex(
address _wNFTAddress,
uint256 _wNFTTokenId,
ETypes.AssetType _collateralType,
address _erc,
uint256 _tokenId
) external view returns (uint256, uint256);
}
文件 22 的 28:LibEnvelopTypes.sol
pragma solidity 0.8.21;
library ETypes {
enum AssetType {EMPTY, NATIVE, ERC20, ERC721, ERC1155, FUTURE1, FUTURE2, FUTURE3}
struct Asset {
AssetType assetType;
address contractAddress;
}
struct AssetItem {
Asset asset;
uint256 tokenId;
uint256 amount;
}
struct NFTItem {
address contractAddress;
uint256 tokenId;
}
struct Fee {
bytes1 feeType;
uint256 param;
address token;
}
struct Lock {
bytes1 lockType;
uint256 param;
}
struct Royalty {
address beneficiary;
uint16 percent;
}
struct WNFT {
AssetItem inAsset;
AssetItem[] collateral;
address unWrapDestination;
Fee[] fees;
Lock[] locks;
Royalty[] royalties;
bytes2 rules;
}
struct INData {
AssetItem inAsset;
address unWrapDestination;
Fee[] fees;
Lock[] locks;
Royalty[] royalties;
AssetType outType;
uint256 outBalance;
bytes2 rules;
}
struct WhiteListItem {
bool enabledForFee;
bool enabledForCollateral;
bool enabledRemoveFromCollateral;
address transferFeeModel;
}
struct Rules {
bytes2 onlythis;
bytes2 disabled;
}
}
文件 23 的 28: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() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 24 的 28: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() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 25 的 28:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 26 的 28:TokenService.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../interfaces/IERC20Extended.sol";
import "./LibEnvelopTypes.sol";
import "../interfaces/IERC721Mintable.sol";
import "../interfaces/IERC1155Mintable.sol";
abstract contract TokenService {
using SafeERC20 for IERC20Extended;
error UnSupportedAsset(ETypes.AssetItem asset);
function _mintNFT(
ETypes.AssetType _mint_type,
address _contract,
address _mintFor,
uint256 _tokenId,
uint256 _outBalance
)
internal
virtual
{
if (_mint_type == ETypes.AssetType.ERC721) {
IERC721Mintable(_contract).mint(_mintFor, _tokenId);
} else if (_mint_type == ETypes.AssetType.ERC1155) {
IERC1155Mintable(_contract).mint(_mintFor, _tokenId, _outBalance);
}else {
revert UnSupportedAsset(
ETypes.AssetItem(
ETypes.Asset(_mint_type, _contract),
_tokenId, _outBalance
)
);
}
}
function _burnNFT(
ETypes.AssetType _burn_type,
address _contract,
address _burnFor,
uint256 _tokenId,
uint256 _balance
)
internal
virtual
{
if (_burn_type == ETypes.AssetType.ERC721) {
IERC721Mintable(_contract).burn(_tokenId);
} else if (_burn_type == ETypes.AssetType.ERC1155) {
IERC1155Mintable(_contract).burn(_burnFor, _tokenId, _balance);
}
}
function _transfer(
ETypes.AssetItem memory _assetItem,
address _from,
address _to
) internal virtual returns (bool _transfered){
if (_assetItem.asset.assetType == ETypes.AssetType.NATIVE) {
(bool success, ) = _to.call{ value: _assetItem.amount}("");
require(success, "transfer failed");
_transfered = true;
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC20) {
require(IERC20Extended(_assetItem.asset.contractAddress).balanceOf(_from) <= _assetItem.amount, "UPS!!!!");
IERC20Extended(_assetItem.asset.contractAddress).safeTransferFrom(_from, _to, _assetItem.amount);
_transfered = true;
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC721) {
IERC721Mintable(_assetItem.asset.contractAddress).transferFrom(_from, _to, _assetItem.tokenId);
_transfered = true;
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC1155) {
IERC1155Mintable(_assetItem.asset.contractAddress).safeTransferFrom(_from, _to, _assetItem.tokenId, _assetItem.amount, "");
_transfered = true;
} else {
revert UnSupportedAsset(_assetItem);
}
return _transfered;
}
function _transferSafe(
ETypes.AssetItem memory _assetItem,
address _from,
address _to
) internal virtual returns (uint256 _transferedValue){
uint256 balanceBefore;
if (_assetItem.asset.assetType == ETypes.AssetType.NATIVE) {
balanceBefore = _to.balance;
(bool success, ) = _to.call{ value: _assetItem.amount}("");
require(success, "transfer failed");
_transferedValue = _to.balance - balanceBefore;
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC20) {
balanceBefore = IERC20Extended(_assetItem.asset.contractAddress).balanceOf(_to);
if (_from == address(this)){
IERC20Extended(_assetItem.asset.contractAddress).safeTransfer(_to, _assetItem.amount);
} else {
IERC20Extended(_assetItem.asset.contractAddress).safeTransferFrom(_from, _to, _assetItem.amount);
}
_transferedValue = IERC20Extended(_assetItem.asset.contractAddress).balanceOf(_to) - balanceBefore;
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC721 &&
IERC721Mintable(_assetItem.asset.contractAddress).ownerOf(_assetItem.tokenId) == _from) {
balanceBefore = IERC721Mintable(_assetItem.asset.contractAddress).balanceOf(_to);
IERC721Mintable(_assetItem.asset.contractAddress).transferFrom(_from, _to, _assetItem.tokenId);
if (IERC721Mintable(_assetItem.asset.contractAddress).ownerOf(_assetItem.tokenId) == _to &&
IERC721Mintable(_assetItem.asset.contractAddress).balanceOf(_to) - balanceBefore == 1
) {
_transferedValue = 1;
}
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC1155) {
balanceBefore = IERC1155Mintable(_assetItem.asset.contractAddress).balanceOf(_to, _assetItem.tokenId);
IERC1155Mintable(_assetItem.asset.contractAddress).safeTransferFrom(_from, _to, _assetItem.tokenId, _assetItem.amount, "");
_transferedValue = IERC1155Mintable(_assetItem.asset.contractAddress).balanceOf(_to, _assetItem.tokenId) - balanceBefore;
} else {
revert UnSupportedAsset(_assetItem);
}
return _transferedValue;
}
function _transferEmergency(
ETypes.AssetItem memory _assetItem,
address _from,
address _to
) internal virtual returns (uint256 _transferedValue){
uint256 balanceBefore;
if (_assetItem.asset.assetType == ETypes.AssetType.NATIVE) {
balanceBefore = _to.balance;
(bool success, ) = _to.call{ value: _assetItem.amount}("");
_transferedValue = _to.balance - balanceBefore;
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC20) {
if (_from == address(this)){
(bool success, ) = _assetItem.asset.contractAddress.call(
abi.encodeWithSignature("transfer(address,uint256)", _to, _assetItem.amount)
);
} else {
(bool success, ) = _assetItem.asset.contractAddress.call(
abi.encodeWithSignature("transferFrom(address,address,uint256)", _from, _to, _assetItem.amount)
);
}
_transferedValue = _assetItem.amount;
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC721) {
(bool success, ) = _assetItem.asset.contractAddress.call(
abi.encodeWithSignature("transferFrom(address,address,uint256)", _from, _to, _assetItem.tokenId)
);
_transferedValue = 1;
} else if (_assetItem.asset.assetType == ETypes.AssetType.ERC1155) {
(bool success, ) = _assetItem.asset.contractAddress.call(
abi.encodeWithSignature("safeTransferFrom(address,address,uint256,uint256,bytes)", _from, _to, _assetItem.tokenId, _assetItem.amount, "")
);
_transferedValue = _assetItem.amount;
} else {
revert UnSupportedAsset(_assetItem);
}
return _transferedValue;
}
}
文件 27 的 28:TrustedWrapperV2.sol
import "@envelop-protocol-v1/contracts/WrapperBaseV1.sol";
pragma solidity 0.8.21;
contract TrustedWrapperV2 is WrapperBaseV1 {
mapping(address => bool) public trustedOperator;
constructor (address _erc20, address _trusted)
WrapperBaseV1(_erc20)
{
trustedOperator[_trusted] = true;
}
modifier onlyTrusted() {
require (trustedOperator[msg.sender], "Only trusted address");
_;
}
function wrapUnsafe(
ETypes.INData calldata _inData,
ETypes.AssetItem[] calldata _collateral,
address _wrappFor
)
public
virtual
payable
onlyTrusted
nonReentrant
returns (ETypes.AssetItem memory)
{
_mintNFT(
_inData.outType,
lastWNFTId[_inData.outType].contractAddress,
_wrappFor,
lastWNFTId[_inData.outType].tokenId + 1,
_inData.outBalance
);
lastWNFTId[_inData.outType].tokenId += 1;
_saveWNFTinfo(
lastWNFTId[_inData.outType].contractAddress,
lastWNFTId[_inData.outType].tokenId,
_inData
);
for (uint256 i = 0; i <_collateral.length; i ++) {
_updateCollateralInfo(
lastWNFTId[_inData.outType].contractAddress,
lastWNFTId[_inData.outType].tokenId,
_collateral[i]
);
emit CollateralAdded(
lastWNFTId[_inData.outType].contractAddress,
lastWNFTId[_inData.outType].tokenId,
uint8(_collateral[i].asset.assetType),
_collateral[i].asset.contractAddress,
_collateral[i].tokenId,
_collateral[i].amount
);
}
emit WrappedV1(
_inData.inAsset.asset.contractAddress,
lastWNFTId[_inData.outType].contractAddress,
_inData.inAsset.tokenId,
lastWNFTId[_inData.outType].tokenId,
_wrappFor,
msg.value,
_inData.rules
);
return ETypes.AssetItem(
ETypes.Asset(_inData.outType, lastWNFTId[_inData.outType].contractAddress),
lastWNFTId[_inData.outType].tokenId,
_inData.outBalance
);
}
function transferIn(
ETypes.AssetItem memory _assetItem,
address _from
)
external
onlyTrusted
nonReentrant
returns (uint256 _transferedValue)
{
return _transferSafe(_assetItem, _from, address(this));
}
function setMaxCollateralSlots(uint256 _count) external onlyOwner {
MAX_COLLATERAL_SLOTS = _count;
}
function setTrustedOperatorStatus(address _operator, bool _status)
external onlyOwner
{
trustedOperator[_operator] = _status;
}
}
文件 28 的 28:WrapperBaseV1.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "../interfaces/IFeeRoyaltyModel.sol";
import "../interfaces/IWrapper.sol";
import "../interfaces/IAdvancedWhiteList.sol";
import "./TokenService.sol";
contract WrapperBaseV1 is
ReentrancyGuard,
ERC721Holder,
ERC1155Holder,
IWrapper,
TokenService,
Ownable
{
uint256 public MAX_COLLATERAL_SLOTS = 25;
address public protocolTechToken;
address public protocolWhiteList;
mapping(ETypes.AssetType => ETypes.NFTItem) public lastWNFTId;
mapping(address => ETypes.AssetType) public wnftTypes;
mapping(address => mapping(uint256 => ETypes.WNFT)) internal wrappedTokens;
constructor(address _erc20) {
require(_erc20 != address(0), "ProtocolTechToken cant be zero value");
protocolTechToken = _erc20;
IFeeRoyaltyModel(protocolTechToken).registerModel();
}
function wrap(
ETypes.INData calldata _inData,
ETypes.AssetItem[] calldata _collateral,
address _wrappFor
)
public
virtual
payable
nonReentrant
returns (ETypes.AssetItem memory)
{
require(_checkWrap(_inData,_wrappFor),
"Wrap check fail"
);
if ( _inData.inAsset.asset.assetType != ETypes.AssetType.NATIVE &&
_inData.inAsset.asset.assetType != ETypes.AssetType.EMPTY
)
{
require(
_mustTransfered(_inData.inAsset) == _transferSafe(
_inData.inAsset,
msg.sender,
address(this)
),
"Suspicious asset for wrap"
);
}
lastWNFTId[_inData.outType].tokenId += 1;
_mintNFT(
_inData.outType,
lastWNFTId[_inData.outType].contractAddress,
_wrappFor,
lastWNFTId[_inData.outType].tokenId,
_inData.outBalance
);
_saveWNFTinfo(
lastWNFTId[_inData.outType].contractAddress,
lastWNFTId[_inData.outType].tokenId,
_inData
);
addCollateral(
lastWNFTId[_inData.outType].contractAddress,
lastWNFTId[_inData.outType].tokenId,
_collateral
);
_chargeFees(
lastWNFTId[_inData.outType].contractAddress,
lastWNFTId[_inData.outType].tokenId,
msg.sender,
address(this),
0x02
);
emit WrappedV1(
_inData.inAsset.asset.contractAddress,
lastWNFTId[_inData.outType].contractAddress,
_inData.inAsset.tokenId,
lastWNFTId[_inData.outType].tokenId,
_wrappFor,
msg.value,
_inData.rules
);
return ETypes.AssetItem(
ETypes.Asset(_inData.outType, lastWNFTId[_inData.outType].contractAddress),
lastWNFTId[_inData.outType].tokenId,
_inData.outBalance
);
}
function addCollateral(
address _wNFTAddress,
uint256 _wNFTTokenId,
ETypes.AssetItem[] calldata _collateral
) public payable virtual {
if (_collateral.length > 0 || msg.value > 0) {
require(
_checkAddCollateral(
_wNFTAddress,
_wNFTTokenId,
_collateral
),
"Forbidden add collateral"
);
_addCollateral(
_wNFTAddress,
_wNFTTokenId,
_collateral
);
}
}
function unWrap(address _wNFTAddress, uint256 _wNFTTokenId) external virtual {
unWrap(wnftTypes[_wNFTAddress], _wNFTAddress, _wNFTTokenId, false);
}
function unWrap(
ETypes.AssetType _wNFTType,
address _wNFTAddress,
uint256 _wNFTTokenId
) external virtual {
unWrap(_wNFTType, _wNFTAddress, _wNFTTokenId, false);
}
function unWrap(
ETypes.AssetType _wNFTType,
address _wNFTAddress,
uint256 _wNFTTokenId,
bool _isEmergency
) public virtual {
(address burnFor, uint256 burnBalance) = _checkCoreUnwrap(_wNFTType, _wNFTAddress, _wNFTTokenId);
require(
_checkLocks(_wNFTAddress, _wNFTTokenId)
);
_chargeFees(_wNFTAddress, _wNFTTokenId, msg.sender, address(this), 0x03);
(uint256 nativeCollateralAmount, ) = getCollateralBalanceAndIndex(
_wNFTAddress,
_wNFTTokenId,
ETypes.AssetType.NATIVE,
address(0),
0
);
if (!_beforeUnWrapHook(_wNFTAddress, _wNFTTokenId, _isEmergency)) {
return;
}
_burnNFT(
_wNFTType,
_wNFTAddress,
burnFor,
_wNFTTokenId,
burnBalance
);
emit UnWrappedV1(
_wNFTAddress,
wrappedTokens[_wNFTAddress][_wNFTTokenId].inAsset.asset.contractAddress,
_wNFTTokenId,
wrappedTokens[_wNFTAddress][_wNFTTokenId].inAsset.tokenId,
wrappedTokens[_wNFTAddress][_wNFTTokenId].unWrapDestination,
nativeCollateralAmount,
wrappedTokens[_wNFTAddress][_wNFTTokenId].rules
);
}
function chargeFees(
address _wNFTAddress,
uint256 _wNFTTokenId,
address _from,
address _to,
bytes1 _feeType
)
public
virtual
returns (bool charged)
{
require(msg.sender == _wNFTAddress || msg.sender == address(this),
"Only for wNFT or wrapper"
);
require(_chargeFees(_wNFTAddress, _wNFTTokenId, _from, _to, _feeType),
"Fee charge fail"
);
charged = true;
}
function setWNFTId(
ETypes.AssetType _assetOutType,
address _wnftContract,
uint256 _tokenId
) external onlyOwner {
require(_wnftContract != address(0), "No zero address");
lastWNFTId[_assetOutType] = ETypes.NFTItem(_wnftContract, _tokenId);
wnftTypes[_wnftContract] = _assetOutType;
}
function setWhiteList(address _wlAddress) external onlyOwner {
protocolWhiteList = _wlAddress;
}
function getWrappedToken(address _wNFTAddress, uint256 _wNFTTokenId)
public
view
returns (ETypes.WNFT memory)
{
return wrappedTokens[_wNFTAddress][_wNFTTokenId];
}
function getOriginalURI(address _wNFTAddress, uint256 _wNFTTokenId)
public
view
returns(string memory uri_)
{
ETypes.AssetItem memory _wnftInAsset = getWrappedToken(
_wNFTAddress, _wNFTTokenId
).inAsset;
if (_wnftInAsset.asset.assetType == ETypes.AssetType.ERC721) {
uri_ = IERC721Metadata(_wnftInAsset.asset.contractAddress).tokenURI(_wnftInAsset.tokenId);
} else if (_wnftInAsset.asset.assetType == ETypes.AssetType.ERC1155) {
uri_ = IERC1155MetadataURI(_wnftInAsset.asset.contractAddress).uri(_wnftInAsset.tokenId);
} else {
uri_ = '';
}
}
function getCollateralBalanceAndIndex(
address _wNFTAddress,
uint256 _wNFTTokenId,
ETypes.AssetType _collateralType,
address _erc,
uint256 _tokenId
) public view returns (uint256, uint256)
{
for (uint256 i = 0; i < wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral.length; i ++) {
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i].asset.contractAddress == _erc &&
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i].tokenId == _tokenId &&
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i].asset.assetType == _collateralType
)
{
return (wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i].amount, i);
}
}
}
function _saveWNFTinfo(
address wNFTAddress,
uint256 tokenId,
ETypes.INData calldata _inData
) internal virtual
{
wrappedTokens[wNFTAddress][tokenId].inAsset = _inData.inAsset;
wrappedTokens[wNFTAddress][tokenId].unWrapDestination = address(0);
wrappedTokens[wNFTAddress][tokenId].rules = _inData.rules;
for (uint256 i = 0; i < _inData.fees.length; i ++) {
wrappedTokens[wNFTAddress][tokenId].fees.push(_inData.fees[i]);
}
for (uint256 i = 0; i < _inData.locks.length; i ++) {
wrappedTokens[wNFTAddress][tokenId].locks.push(_inData.locks[i]);
}
for (uint256 i = 0; i < _inData.royalties.length; i ++) {
wrappedTokens[wNFTAddress][tokenId].royalties.push(_inData.royalties[i]);
}
}
function _addCollateral(
address _wNFTAddress,
uint256 _wNFTTokenId,
ETypes.AssetItem[] calldata _collateral
) internal virtual
{
if (msg.value > 0) {
_updateCollateralInfo(
_wNFTAddress,
_wNFTTokenId,
ETypes.AssetItem(
ETypes.Asset(ETypes.AssetType.NATIVE, address(0)),
0,
msg.value
)
);
emit CollateralAdded(
_wNFTAddress,
_wNFTTokenId,
uint8(ETypes.AssetType.NATIVE),
address(0),
0,
msg.value
);
}
for (uint256 i = 0; i <_collateral.length; i ++) {
if (_collateral[i].asset.assetType != ETypes.AssetType.NATIVE) {
if (protocolWhiteList != address(0)) {
require(
IAdvancedWhiteList(protocolWhiteList).enabledForCollateral(
_collateral[i].asset.contractAddress),
"WL:Some assets are not enabled for collateral"
);
}
require(
_mustTransfered(_collateral[i]) == _transferSafe(
_collateral[i],
msg.sender,
address(this)
),
"Suspicious asset for wrap"
);
_updateCollateralInfo(
_wNFTAddress,
_wNFTTokenId,
_collateral[i]
);
emit CollateralAdded(
_wNFTAddress,
_wNFTTokenId,
uint8(_collateral[i].asset.assetType),
_collateral[i].asset.contractAddress,
_collateral[i].tokenId,
_collateral[i].amount
);
}
}
}
function _updateCollateralInfo(
address _wNFTAddress,
uint256 _wNFTTokenId,
ETypes.AssetItem memory collateralItem
) internal virtual
{
if (collateralItem.asset.assetType == ETypes.AssetType.ERC20 ||
collateralItem.asset.assetType == ETypes.AssetType.NATIVE)
{
require(collateralItem.tokenId == 0, "TokenId must be zero");
}
if (collateralItem.asset.assetType == ETypes.AssetType.ERC721 ) {
require(collateralItem.amount == 0, "Amount must be zero");
}
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral.length == 0
|| collateralItem.asset.assetType == ETypes.AssetType.ERC721
)
{
_newCollateralItem(_wNFTAddress,_wNFTTokenId,collateralItem);
} else {
(, uint256 _index) = getCollateralBalanceAndIndex(
_wNFTAddress,
_wNFTTokenId,
collateralItem.asset.assetType,
collateralItem.asset.contractAddress,
collateralItem.tokenId
);
if (_index > 0 ||
(_index == 0
&& wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[0].asset.contractAddress
== collateralItem.asset.contractAddress
)
)
{
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[_index].amount
+= collateralItem.amount;
} else {
_newCollateralItem(_wNFTAddress,_wNFTTokenId,collateralItem);
}
}
}
function _newCollateralItem(
address _wNFTAddress,
uint256 _wNFTTokenId,
ETypes.AssetItem memory collateralItem
) internal virtual
{
require(
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral.length < MAX_COLLATERAL_SLOTS,
"Too much tokens in collateral"
);
for (uint256 i = 0; i < wrappedTokens[_wNFTAddress][_wNFTTokenId].locks.length; i ++)
{
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].locks[i].lockType == 0x02) {
require(
wrappedTokens[_wNFTAddress][_wNFTTokenId].locks[i].param
>= (wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral.length + 1),
"Too much collateral slots for this wNFT"
);
}
}
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral.push(collateralItem);
}
function _chargeFees(
address _wNFTAddress,
uint256 _wNFTTokenId,
address _from,
address _to,
bytes1 _feeType
)
internal
virtual
returns (bool _charged)
{
if (_feeType == 0x00) {
for (uint256 i = 0; i < wrappedTokens[_wNFTAddress][_wNFTTokenId].fees.length; i ++){
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].fees[i].feeType == 0x00){
address feeModel = protocolTechToken;
if (protocolWhiteList != address(0)) {
feeModel = IAdvancedWhiteList(protocolWhiteList).getWLItem(
wrappedTokens[_wNFTAddress][_wNFTTokenId].fees[i].token).transferFeeModel;
}
(ETypes.AssetItem[] memory assetItems,
address[] memory from,
address[] memory to
) =
IFeeRoyaltyModel(feeModel).getTransfersList(
wrappedTokens[_wNFTAddress][_wNFTTokenId].fees[i],
wrappedTokens[_wNFTAddress][_wNFTTokenId].royalties,
_from,
_to
);
uint256 actualTransfered;
for (uint256 j = 0; j < to.length; j ++){
if (to[j]== address(this)){
_updateCollateralInfo(
_wNFTAddress,
_wNFTTokenId,
assetItems[j]
);
}
actualTransfered = _transferSafe(assetItems[j], from[j], to[j]);
emit EnvelopFee(to[j], _wNFTAddress, _wNFTTokenId, actualTransfered);
}
}
}
_charged = true;
}
}
function _beforeUnWrapHook(
address _wNFTAddress,
uint256 _wNFTTokenId,
bool _emergency
) internal virtual returns (bool)
{
uint256 transfered;
address receiver = msg.sender;
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].unWrapDestination != address(0)) {
receiver = wrappedTokens[_wNFTAddress][_wNFTTokenId].unWrapDestination;
}
for (uint256 i = 0; i < wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral.length; i ++) {
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i].asset.assetType
!= ETypes.AssetType.EMPTY
) {
if (_emergency) {
transfered = _transferEmergency(
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i],
address(this),
receiver
);
} else {
transfered = _transferSafe(
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i],
address(this),
receiver
);
}
if (transfered != wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i].amount ) {
emit SuspiciousFail(
_wNFTAddress,
_wNFTTokenId,
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i].asset.contractAddress
);
}
wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral[i].asset.assetType = ETypes.AssetType.EMPTY;
}
if (
gasleft() <= 1_000 &&
i < wrappedTokens[_wNFTAddress][_wNFTTokenId].collateral.length - 1
)
{
emit PartialUnWrapp(_wNFTAddress, _wNFTTokenId, i);
return false;
}
}
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].inAsset.asset.assetType != ETypes.AssetType.NATIVE &&
wrappedTokens[_wNFTAddress][_wNFTTokenId].inAsset.asset.assetType != ETypes.AssetType.EMPTY
)
{
if (!_emergency){
_transferSafe(
wrappedTokens[_wNFTAddress][_wNFTTokenId].inAsset,
address(this),
receiver
);
} else {
_transferEmergency (
wrappedTokens[_wNFTAddress][_wNFTTokenId].inAsset,
address(this),
receiver
);
}
}
return true;
}
function _mustTransfered(ETypes.AssetItem calldata _assetForTransfer)
internal
pure
returns (uint256 mustTransfered)
{
if (_assetForTransfer.asset.assetType == ETypes.AssetType.ERC721) {
mustTransfered = 1;
} else {
mustTransfered = _assetForTransfer.amount;
}
}
function _checkRule(bytes2 _rule, bytes2 _wNFTrules) internal pure returns (bool) {
return _rule == (_rule & _wNFTrules);
}
function _checkLocks(address _wNFTAddress, uint256 _wNFTTokenId) internal view returns (bool)
{
for (uint256 i = 0; i < wrappedTokens[_wNFTAddress][_wNFTTokenId].locks.length; i ++) {
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].locks[i].lockType == 0x00) {
require(
wrappedTokens[_wNFTAddress][_wNFTTokenId].locks[i].param <= block.timestamp,
"TimeLock error"
);
}
if (wrappedTokens[_wNFTAddress][_wNFTTokenId].locks[i].lockType == 0x01) {
for (uint256 j = 0; j < wrappedTokens[_wNFTAddress][_wNFTTokenId].fees.length; j ++){
if ( wrappedTokens[_wNFTAddress][_wNFTTokenId].fees[j].feeType == 0x00) {
(uint256 _bal,) = getCollateralBalanceAndIndex(
_wNFTAddress,
_wNFTTokenId,
ETypes.AssetType.ERC20,
wrappedTokens[_wNFTAddress][_wNFTTokenId].fees[j].token,
0
);
require(
wrappedTokens[_wNFTAddress][_wNFTTokenId].locks[i].param <= _bal,
"TransferFeeLock error"
);
}
}
}
}
return true;
}
function _checkWrap(ETypes.INData calldata _inData, address _wrappFor)
internal
view
returns (bool enabled)
{
enabled = !_checkRule(0x0002, getWrappedToken(
_inData.inAsset.asset.contractAddress,
_inData.inAsset.tokenId).rules
)
&& _wrappFor != address(this);
if (protocolWhiteList != address(0)) {
require(
!IAdvancedWhiteList(protocolWhiteList).getBLItem(_inData.inAsset.asset.contractAddress),
"WL:Asset disabled for wrap"
);
require(
IAdvancedWhiteList(protocolWhiteList).rulesEnabled(_inData.inAsset.asset.contractAddress, _inData.rules),
"WL:Some rules are disabled for this asset"
);
for (uint256 i = 0; i < _inData.fees.length; i ++){
require(
IAdvancedWhiteList(protocolWhiteList).enabledForFee(
_inData.fees[i].token),
"WL:Some assets are not enabled for fee"
);
}
}
}
function _checkAddCollateral(
address _wNFTAddress,
uint256 _wNFTTokenId,
ETypes.AssetItem[] calldata _collateral
)
internal
view
returns (bool enabled)
{
if (wnftTypes[_wNFTAddress] == ETypes.AssetType.ERC721) {
require(IERC721Mintable(_wNFTAddress).exists(_wNFTTokenId), "wNFT not exists");
} else if(wnftTypes[_wNFTAddress] == ETypes.AssetType.ERC1155) {
require(IERC1155Mintable(_wNFTAddress).exists(_wNFTTokenId), "wNFT not exists");
} else {
revert UnSupportedAsset(
ETypes.AssetItem(ETypes.Asset(wnftTypes[_wNFTAddress],_wNFTAddress),_wNFTTokenId, 0)
);
}
enabled = !_checkRule(0x0008, getWrappedToken(_wNFTAddress, _wNFTTokenId).rules);
}
function _checkCoreUnwrap(
ETypes.AssetType _wNFTType,
address _wNFTAddress,
uint256 _wNFTTokenId
)
internal
view
virtual
returns (address burnFor, uint256 burnBalance)
{
require(!_checkRule(0x0001, getWrappedToken(_wNFTAddress, _wNFTTokenId).rules),
"UnWrapp forbidden by author"
);
if (_wNFTType == ETypes.AssetType.ERC721) {
burnFor = IERC721Mintable(_wNFTAddress).ownerOf(_wNFTTokenId);
require(burnFor == msg.sender,
'Only owner can unwrap it'
);
} else if (_wNFTType == ETypes.AssetType.ERC1155) {
burnBalance = IERC1155Mintable(_wNFTAddress).totalSupply(_wNFTTokenId);
burnFor = msg.sender;
require(
burnBalance ==
IERC1155Mintable(_wNFTAddress).balanceOf(burnFor, _wNFTTokenId)
,'ERC115 unwrap available only for all totalSupply'
);
} else {
revert UnSupportedAsset(ETypes.AssetItem(ETypes.Asset(_wNFTType,_wNFTAddress),_wNFTTokenId, 0));
}
}
}
{
"compilationTarget": {
"contracts/TrustedWrapperV2.sol": "TrustedWrapperV2"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@envelop-protocol-v1/=lib/envelop-protocol-v1/",
":@envelop-subscription/=lib/subscription/",
":@openzeppelin/=lib/openzeppelin-contracts/",
":@uniswap/=lib/",
":ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
":envelop-protocol-v1/=lib/envelop-protocol-v1/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/",
":openzeppelin/=lib/openzeppelin-contracts/contracts/",
":subscription/=lib/subscription/"
]
}
[{"inputs":[{"internalType":"address","name":"_erc20","type":"address"},{"internalType":"address","name":"_trusted","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem","name":"asset","type":"tuple"}],"name":"UnSupportedAsset","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wrappedAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"wrappedId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"assetType","type":"uint8"},{"indexed":false,"internalType":"address","name":"collateralAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralBalance","type":"uint256"}],"name":"CollateralAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"wNFTConatract","type":"address"},{"indexed":true,"internalType":"uint256","name":"wNFTTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EnvelopFee","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":"wrappedAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"wrappedId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastCollateralIndex","type":"uint256"}],"name":"PartialUnWrapp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wrappedAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"wrappedId","type":"uint256"},{"indexed":true,"internalType":"address","name":"failedContractAddress","type":"address"}],"name":"SuspiciousFail","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wrappedAddress","type":"address"},{"indexed":true,"internalType":"address","name":"originalAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"wrappedId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"originalTokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"nativeCollateralAmount","type":"uint256"},{"indexed":false,"internalType":"bytes2","name":"rules","type":"bytes2"}],"name":"UnWrappedV1","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"inAssetAddress","type":"address"},{"indexed":true,"internalType":"address","name":"outAssetAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"inAssetTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outTokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"wnftFirstOwner","type":"address"},{"indexed":false,"internalType":"uint256","name":"nativeCollateralAmount","type":"uint256"},{"indexed":false,"internalType":"bytes2","name":"rules","type":"bytes2"}],"name":"WrappedV1","type":"event"},{"inputs":[],"name":"MAX_COLLATERAL_SLOTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wNFTAddress","type":"address"},{"internalType":"uint256","name":"_wNFTTokenId","type":"uint256"},{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem[]","name":"_collateral","type":"tuple[]"}],"name":"addCollateral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_wNFTAddress","type":"address"},{"internalType":"uint256","name":"_wNFTTokenId","type":"uint256"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes1","name":"_feeType","type":"bytes1"}],"name":"chargeFees","outputs":[{"internalType":"bool","name":"charged","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wNFTAddress","type":"address"},{"internalType":"uint256","name":"_wNFTTokenId","type":"uint256"},{"internalType":"enum ETypes.AssetType","name":"_collateralType","type":"uint8"},{"internalType":"address","name":"_erc","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getCollateralBalanceAndIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wNFTAddress","type":"address"},{"internalType":"uint256","name":"_wNFTTokenId","type":"uint256"}],"name":"getOriginalURI","outputs":[{"internalType":"string","name":"uri_","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wNFTAddress","type":"address"},{"internalType":"uint256","name":"_wNFTTokenId","type":"uint256"}],"name":"getWrappedToken","outputs":[{"components":[{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem","name":"inAsset","type":"tuple"},{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem[]","name":"collateral","type":"tuple[]"},{"internalType":"address","name":"unWrapDestination","type":"address"},{"components":[{"internalType":"bytes1","name":"feeType","type":"bytes1"},{"internalType":"uint256","name":"param","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"internalType":"struct ETypes.Fee[]","name":"fees","type":"tuple[]"},{"components":[{"internalType":"bytes1","name":"lockType","type":"bytes1"},{"internalType":"uint256","name":"param","type":"uint256"}],"internalType":"struct ETypes.Lock[]","name":"locks","type":"tuple[]"},{"components":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint16","name":"percent","type":"uint16"}],"internalType":"struct ETypes.Royalty[]","name":"royalties","type":"tuple[]"},{"internalType":"bytes2","name":"rules","type":"bytes2"}],"internalType":"struct ETypes.WNFT","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum ETypes.AssetType","name":"","type":"uint8"}],"name":"lastWNFTId","outputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","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":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolTechToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolWhiteList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"setMaxCollateralSlots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"setTrustedOperatorStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum ETypes.AssetType","name":"_assetOutType","type":"uint8"},{"internalType":"address","name":"_wnftContract","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"setWNFTId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wlAddress","type":"address"}],"name":"setWhiteList","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":[{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem","name":"_assetItem","type":"tuple"},{"internalType":"address","name":"_from","type":"address"}],"name":"transferIn","outputs":[{"internalType":"uint256","name":"_transferedValue","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"trustedOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum ETypes.AssetType","name":"_wNFTType","type":"uint8"},{"internalType":"address","name":"_wNFTAddress","type":"address"},{"internalType":"uint256","name":"_wNFTTokenId","type":"uint256"},{"internalType":"bool","name":"_isEmergency","type":"bool"}],"name":"unWrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum ETypes.AssetType","name":"_wNFTType","type":"uint8"},{"internalType":"address","name":"_wNFTAddress","type":"address"},{"internalType":"uint256","name":"_wNFTTokenId","type":"uint256"}],"name":"unWrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wNFTAddress","type":"address"},{"internalType":"uint256","name":"_wNFTTokenId","type":"uint256"}],"name":"unWrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wnftTypes","outputs":[{"internalType":"enum ETypes.AssetType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem","name":"inAsset","type":"tuple"},{"internalType":"address","name":"unWrapDestination","type":"address"},{"components":[{"internalType":"bytes1","name":"feeType","type":"bytes1"},{"internalType":"uint256","name":"param","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"internalType":"struct ETypes.Fee[]","name":"fees","type":"tuple[]"},{"components":[{"internalType":"bytes1","name":"lockType","type":"bytes1"},{"internalType":"uint256","name":"param","type":"uint256"}],"internalType":"struct ETypes.Lock[]","name":"locks","type":"tuple[]"},{"components":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint16","name":"percent","type":"uint16"}],"internalType":"struct ETypes.Royalty[]","name":"royalties","type":"tuple[]"},{"internalType":"enum ETypes.AssetType","name":"outType","type":"uint8"},{"internalType":"uint256","name":"outBalance","type":"uint256"},{"internalType":"bytes2","name":"rules","type":"bytes2"}],"internalType":"struct ETypes.INData","name":"_inData","type":"tuple"},{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem[]","name":"_collateral","type":"tuple[]"},{"internalType":"address","name":"_wrappFor","type":"address"}],"name":"wrap","outputs":[{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem","name":"","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem","name":"inAsset","type":"tuple"},{"internalType":"address","name":"unWrapDestination","type":"address"},{"components":[{"internalType":"bytes1","name":"feeType","type":"bytes1"},{"internalType":"uint256","name":"param","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"internalType":"struct ETypes.Fee[]","name":"fees","type":"tuple[]"},{"components":[{"internalType":"bytes1","name":"lockType","type":"bytes1"},{"internalType":"uint256","name":"param","type":"uint256"}],"internalType":"struct ETypes.Lock[]","name":"locks","type":"tuple[]"},{"components":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint16","name":"percent","type":"uint16"}],"internalType":"struct ETypes.Royalty[]","name":"royalties","type":"tuple[]"},{"internalType":"enum ETypes.AssetType","name":"outType","type":"uint8"},{"internalType":"uint256","name":"outBalance","type":"uint256"},{"internalType":"bytes2","name":"rules","type":"bytes2"}],"internalType":"struct ETypes.INData","name":"_inData","type":"tuple"},{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem[]","name":"_collateral","type":"tuple[]"},{"internalType":"address","name":"_wrappFor","type":"address"}],"name":"wrapUnsafe","outputs":[{"components":[{"components":[{"internalType":"enum ETypes.AssetType","name":"assetType","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct ETypes.Asset","name":"asset","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ETypes.AssetItem","name":"","type":"tuple"}],"stateMutability":"payable","type":"function"}]